最近做pad项目,需要加入左侧右滑退出界面的功能。安卓要实现这个功能,我的思路是将这个activity 对话框化。
<style name="ItemDetail" parent="AppTheme">
<item name="android:windowBackground">@android:color/transparent</item>
<item name="android:windowFrame">@null</item>
<item name="android:windowIsFloating">true</item>
</style>
将activity的theme指定成上面的ItemDetail , activity就变成了dialog啦,当然你也可以直接指定为系统的dialog样式。
activity变成了dialog样式, window的大小都变成了wrap_content属性了。所以我们在activity的onCreate中设置window的大小。
WindowManager.LayoutParams params = getWindow().getAttributes() ;
DisplayMetrics dm = getResources().getDisplayMetrics() ;
params.width = dm.widthPixels ;
params.height = dm.heightPixels ;
onWindowAttributesChanged(params);这样变将window设置成全屏大小啦!
activity的准备工作已经好啦!接着需要监听左侧滑动监听啦!
package com.czy.slideback;
import android.content.Context;
import android.util.AttributeSet;
import android.util.Log;
import android.util.TypedValue;
import android.view.MotionEvent;
import android.widget.LinearLayout;
/**
* Created by nahuo16 on 2015/6/18.
*/
public class TouchLinearLayout extends LinearLayout {
private final int barHeight;
private OnTouchListener touchListener ;
private boolean shouldListener ;
private int side ;
private int downX, downY;
private int canBackSide ;
public TouchLinearLayout(Context context) {
this(context, null);
}
public TouchLinearLayout(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public TouchLinearLayout(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
side = dip2px(context, 80) ;
canBackSide = dip2px(context, 20) ;
TypedValue value = new TypedValue();
context.getTheme().resolveAttribute(R.attr.actionBarSize, value, true);
barHeight = context.getResources().getDimensionPixelSize(value.resourceId);
}
private int dip2px(Context context, int dp) {
return (int) (context.getResources().getDisplayMetrics().density * dp + 0.5f);
}
@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
switch (ev.getAction()){
case MotionEvent.ACTION_DOWN:
downX = (int) ev.getX();
downY = (int) ev.getY();
shouldListener = downX < side && downY > barHeight ;
break ;
case MotionEvent.ACTION_MOVE:
if(shouldListener){
int x = (int) (ev.getX() - downX);
if( x> canBackSide && Math.abs(x / (ev.getY() - downY))>1.1f){
return true ;
}
}
break ;
case MotionEvent.ACTION_CANCEL:
case MotionEvent.ACTION_UP:
break ;
}
return false;
}
@Override
public boolean onTouchEvent(MotionEvent event) {
if(touchListener!=null)
touchListener.onTouch(this , event) ;
return true;
}
public void setOnTouchListener(OnTouchListener l){
touchListener = l ;
}
}
自定义监听左侧滑动监听的线性布局。
将这个线性布局做为根布局。(需要RelativeLayout?将上面的linearLayout换成RelativeLayout即可)。xml布局如下:
<?xml version="1.0" encoding="utf-8"?>
<com.czy.slideback.TouchLinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent" android:layout_height="match_parent"
android:orientation="vertical"
android:background="@android:color/holo_blue_bright">
<android.support.v7.widget.Toolbar
android:id="@+id/bar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="@android:color/black"></android.support.v7.widget.Toolbar>
<Button android:layout_width="wrap_content"
android:layout_height="match_parent"
android:padding="20dp"
android:background="@android:color/white"
android:text="快滑动我这"/>
</com.czy.slideback.TouchLinearLayout>
在activity的oncreate获取到TouchLinearLayout对象后,将下面的onTouchListener对象传给TouchLinearLayout.setOnTouchListener。这样就完成了左侧右滑退出当前界面啦!
private View.OnTouchListener touchListener =new View.OnTouchListener() {
VelocityTracker velocity ;
@Override
public boolean onTouch(final View v, MotionEvent event) {
getWindow().getDecorView().setX(event.getX());
switch (event.getAction()){
case MotionEvent.ACTION_DOWN:
if(velocity == null){
velocity = VelocityTracker.obtain() ;
}
else{
velocity.clear();
}
velocity.addMovement(event);
break ;
case MotionEvent.ACTION_MOVE:
if(velocity == null){
velocity = VelocityTracker.obtain() ;
}
else{
velocity.clear();
}
velocity.addMovement(event);
velocity.computeCurrentVelocity(1000);
break ;
case MotionEvent.ACTION_CANCEL:
case MotionEvent.ACTION_UP:
final int width = v.getWidth() ;
int plus = dip2px(v.getContext() , 20) ;
int add = -plus ;
int max = (int) event.getX();
if(max>width/3 || (velocity!=null&&velocity.getXVelocity()>2000)){
add = plus ;
}
final int a = add ;
final int m = max ;
new Thread(){
public void run(){
int run = m ;
int add = a ;
int addPlus = add / 10 ;
while(run > 0 && run < width ){
try {
Thread.sleep(10) ;
} catch (InterruptedException e) {
e.printStackTrace();
}
run += add ;
add += addPlus ;
final int r = run ;
v.post(new Runnable() {
@Override
public void run() {
getWindow().getDecorView().setX(r);
}
});
}
if(run <= 0){
final int r = 0 ;
v.post(new Runnable() {
@Override
public void run() {
getWindow().getDecorView().setX(r);
}
});
}
else{
final int r = width ;
v.post(new Runnable() {
@Override
public void run() {
getWindow().getDecorView().setX(r);
finish();
}
});
}
}
}.start();
break ;
}
return false;
}
} ;
private int dip2px(Context context, int dp) {
return (int) (context.getResources().getDisplayMetrics().density * dp + 0.5f);
}
demo下载地址