Android之左滑关闭窗口

来源:互联网 发布:为什么30岁不能学java 编辑:程序博客网 时间:2024/06/18 15:57

前言

目前市场很多的APP都带有窗口滑动切换关闭,这种切换,使得用户操作比较爽,而且觉得功能点上也比较大气,在此就是自己总结了一个简易的方法,直接替换在基础窗口里面,使用安卓最基础的方法进行实现;

需求说明

  1. 首先是明确从哪里滑动:一般习惯都是从左边缘开始滑动
  2. 手指在滑动的时候页面进行移动
  3. 松开手指之后,要判断是否滑出关闭,还是恢复以前状态;

实现的代码

一、继承一个帧布局,重写方法:

public class ArActSlidLayout extends FrameLayout {// 页面边缘阴影的宽度默认值private static final int SHADOW_WIDTH = 16;private Activity mActivity;private Scroller mScroller; //安卓自带的一个滑动计算的类,只做计算,不参与逻辑;// 页面边缘的阴影图private Drawable mLeftShadow; // 页面边缘阴影的宽度private int mShadowWidth;private int mInterceptDownX;  //手指按下,拦截的x值private int mLastInterceptX;//记录最后一次坐标private int mLastInterceptY;private int mTouchDownX; //消费的x值private int mLastTouchX;private int mLastTouchY;private boolean isConsumed = false;是否可以滑动public ArActSlidLayout(Context context) {    this(context, null);}public ArActSlidLayout(Context context, AttributeSet attrs) {    this(context, attrs, 0);}public ArActSlidLayout(Context context, AttributeSet attrs, int defStyleAttr) {    super(context, attrs, defStyleAttr);    initView(context);}private void initView(Context context) {    mScroller = new Scroller(context);    mLeftShadow = getResources().getDrawable(R.drawable.left_shadow);//得到阴影的图形    int density = (int) getResources().getDisplayMetrics().density;    mShadowWidth = SHADOW_WIDTH * density;//得到实际像素的宽度;}/** * 绑定Activity */public void bindActivity(Activity activity) {    mActivity = activity;    ViewGroup decorView = (ViewGroup) mActivity.getWindow().getDecorView();    View child = decorView.getChildAt(0);    decorView.removeView(child);    addView(child);    decorView.addView(this);//把整个布局添加的窗口的ViewGroup中;}@Overridepublic boolean onInterceptTouchEvent(MotionEvent ev) {//进行事件的是否拦截    boolean intercept = false;    int x = (int) ev.getX();    int y = (int) ev.getY();    switch (ev.getAction()) {        case MotionEvent.ACTION_DOWN:            intercept = false;            mInterceptDownX = x;            mLastInterceptX = x;            mLastInterceptY = y;            break;        case MotionEvent.ACTION_MOVE:            int deltaX = x - mLastInterceptX;            int deltaY = y - mLastInterceptY;            // 手指处于屏幕边缘,且横向滑动距离大于纵向滑动距离时,拦截事件            if (mInterceptDownX < (getWidth() / 10) && Math.abs(deltaX) > Math.abs(deltaY)) {                intercept = true;//满足这个条件进行拦截;            } else {                intercept = false;            }            mLastInterceptX = x;            mLastInterceptY = y;            break;        case MotionEvent.ACTION_UP:            intercept = false;            mInterceptDownX = mLastInterceptX = mLastInterceptY = 0;//恢复数据;            break;    }    //Log.e("event", " Intercep  " + "  x:  " + x + "  y:  " + y);    return intercept;}@Overridepublic boolean onTouchEvent(MotionEvent ev) {//事件的消费,具体逻辑的编写;    int x = (int) ev.getX();    int y = (int) ev.getY();    switch (ev.getAction()) {        case MotionEvent.ACTION_DOWN:            mTouchDownX = x;            mLastTouchX = x;            mLastTouchY = y;            //Log.e("event", " onTouchEventDOWN  " + "  x:  " + x + "  y:  " + y);            break;        case MotionEvent.ACTION_MOVE:            int deltaX = x - mLastTouchX;            int deltaY = y - mLastTouchY;            if (!isConsumed && mTouchDownX < (getWidth() / 10) && Math.abs(deltaX) > Math.abs(deltaY)) {                isConsumed = true; //移动的条件            }            if (isConsumed) {                int rightMovedX = mLastTouchX - (int) ev.getX();                // 左侧即将滑出屏幕                if (getScrollX() + rightMovedX >= 0) {                     //移动到某一点                    scrollTo(0, 0);                } else {                    //相当于累加的移动                    scrollBy(rightMovedX, 0); //手指滑动移动整个屏幕;负数:代表向右移动 ,反之,像做                }               // Log.e("event", " onTouchEventMOVE  " + "  x:  " + x + "  y:  " + y + " ScrollX:  " + getScrollX() + " rightMovedX: " + rightMovedX);            }            mLastTouchX = x;            mLastTouchY = y;            break;        case MotionEvent.ACTION_UP:            isConsumed = false;            mTouchDownX = mLastTouchX = mLastTouchY = 0; //消除数据;            // 根据手指释放时的位置决定回弹还是关闭            if (-getScrollX() < getWidth() / 3) {                scrollBack();            } else {                scrollClose();            }            //Log.e("event", " onTouchEventUP  " + "  x:  " + x + "  y:  " + y + " ScrollX:  " + getScrollX());            break;    }    //Log.e("event"," onTouchEventAll  " + "  getRawX():  "+ev.getRawX() +"  y:  " +ev.getRawY());    return true;}/** * 滑动返回 */private void scrollBack() {    int startX = getScrollX();    int dx = -getScrollX();    mScroller.startScroll(startX, 0, dx, 0, 300);    invalidate();}/** * 滑动关闭 */private void scrollClose() {    int startX = getScrollX();    int dx = -getScrollX() - getWidth();    //Log.e("event", "  scrollClose:  dx " + dx + "  getWidth " + getWidth());    mScroller.startScroll(startX, 0, dx, 0, 300);    invalidate();}@Overridepublic void computeScroll() {    if (mScroller.computeScrollOffset()) {        scrollTo(mScroller.getCurrX(), 0);        //Log.e("event", "  computeScroll:  " + mScroller.getCurrX());        postInvalidate();    } else if (-getScrollX() >= getWidth()) {        mActivity.finish();        //Log.e("event", "  computeScroll: finish   " + getScrollX());    }}@Overrideprotected void dispatchDraw(Canvas canvas) {    super.dispatchDraw(canvas);    drawShadow(canvas);}/** * 绘制边缘的阴影 */private void drawShadow(Canvas canvas) {    mLeftShadow.setBounds(0, 0, mShadowWidth, getHeight());    canvas.save();    canvas.translate(-mShadowWidth, 0);    mLeftShadow.draw(canvas);    canvas.restore(); }}

二、边缘的阴影left_shadow.xml:

<?xml version="1.0" encoding="utf-8"?><shape xmlns:android="http://schemas.android.com/apk/res/android"android:shape="rectangle"><!--颜色渐变范围--><gradient    android:endColor="#50000000"    android:startColor="#00000000" /></shape>

三、在baseActivity里面添加代码:

public class ArBaseFragActivity extends BaseMMCFragmentActivity {    protected void onCreate(Bundle savedInstanceState) {      super.onCreate(savedInstanceState);    if (setEnableSliding()) {        ArActSlidLayout rootView = new ArActSlidLayout(this);        rootView.bindActivity(this);//绑定需要窗口的布局:     }  } protected boolean setEnableSliding() {//默认返回是需要的,只需继承的时候重写次代码 true : 需要;false :不需要;    return true;  }}

四、总结:这种实现还有不少的方法,我这里只是推荐了自己觉得不错的方法,有需要的童鞋们直接copy项目中去用就行了,里面涉及到很多安卓自带的方法,还需要你们自己消化理解,我在实现代码中也进行了注释,可以帮助你们理解消化,有什么不足的地方,还请你们多多指教,使得我后期改进更多。

原创粉丝点击