最近做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下载地址