安卓开发之使用ViewDragHelper简单实现Activity左滑返回

来源:互联网 发布:软件核心技术及创新点 编辑:程序博客网 时间:2024/04/28 18:44

一、ViewDragHelper

在另一篇博客里介绍了ViewDragHelper,这里就不再介绍了。

ViewDragHelper的使用

二、Activity左滑返回的简单实现

基本思路是使用ViewDragHelper自定义一个ViewGroup(命名为SwipeBackLayout),实现该ViewGroup的左滑效果。

项目效果图

这里写图片描述

一、 基本工作

  1. 为了省去自定义ViewGroup时onMeasure和onLayout的步骤,将SwipeBackLayout继承FrameLayout.

    public class SwipeBackLayout extends FrameLayout
  2. 定义一些成员变量:

    private View mDragView; // 所拖动的子组件,即该布局下的子布局。private ViewDragHelper mViewDragHelper;private int mCurrentX ; // 当前拖动的横坐标private int mCurEdgeFlag = ViewDragHelper.EDGE_LEFT; // 记录当前边缘触发的方向
  3. 在构造函数中完成初始化工作

    private void init() {    // 实例化ViewDragHelper对象,重点是其中的DragBackCallback的实现    mViewDragHelper = ViewDragHelper.create(this,1.0f,new DragBackCallback());    //对ViewDragHelper对象设置边缘触发    mViewDragHelper.setEdgeTrackingEnabled(ViewDragHelper.EDGE_LEFT); }
  4. 将SwipeBackLayoout的触摸/滑动事件交给ViewDragHelper对象处理:

    @Overridepublic void computeScroll() {    if (mViewDragHelper.continueSettling(true)) {        // 持续绘制        invalidate();    }}@Overridepublic boolean onInterceptTouchEvent(MotionEvent ev){    return mViewDragHelper.shouldInterceptTouchEvent(ev);}@Overridepublic boolean onTouchEvent(MotionEvent event) {    mViewDragHelper.processTouchEvent(event);    return true;}
  5. 滑动结束监听接口的设置 :

    private OnFinishScrollListener mFinishScrollListener;//设置滑动结束监听public void setOnFinishScroll(OnFinishScrollListener finishScroll) {    this.mFinishScrollListener = finishScroll;}//滑动结束接口public interface OnFinishScrollListener {    void complete();}

二、DragBackCallback的实现

private class DragBackCallback extends ViewDragHelper.Callback{    @Override    public boolean tryCaptureView(View child, int pointerId) {        return false; // 先不捕捉滑动View    }    @Override    public int clampViewPositionHorizontal(View child, int left, int dx) {        mCurrentX = (left < 0)? 0:left; //记录目前的滑动时的横坐标        return mCurrentX; //只允许mDragView左滑    }    @Override    public int clampViewPositionVertical(View child, int top, int dy) {        return 0;//防止上下滑动    }    @Override    public void onViewReleased(View releasedChild, float xvel, float yvel) {        super.onViewReleased(releasedChild, xvel, yvel);        // 判断当前的边缘触发是否为左边缘        if(mCurEdgeFlag == ViewDragHelper.EDGE_LEFT){            if (mCurrentX > getWidth()/2) {                    // 当滑动横坐标超过布局的一般宽度时,将布局移出屏幕                    mViewDragHelper.settleCapturedViewAt(getWidth(), 0);                }else {                    // 否则回到初始正常状态,回到原点                    mViewDragHelper.settleCapturedViewAt(0, 0);                    mCurrentX = 0;                }            invalidate(); //重绘        }    }    @Override    public void onEdgeDragStarted(int edgeFlags, int pointerId) {        mCurEdgeFlag = edgeFlags; //获取边缘状态        // 捕捉拖动界面        mViewDragHelper.captureChildView(mDragView, pointerId);    }    @Override    public void onViewPositionChanged(View changedView, int left, int top, int dx, int dy) {        super.onViewPositionChanged(changedView, left, top, dx, dy);        //当拖动界面的位置发送变动时调用        if(mCurEdgeFlag==ViewDragHelper.EDGE_LEFT){                当拖动界面的left值大于布局的宽度(即布局退出屏幕时)时,则调用监听事情                if (left >= getWidth()) {                    if (mFinishScrollListener != null) {                        mFinishScrollListener.complete();                    }                }        }    }}

三、SwipeBackLayout的使用

  1. 布局文件xml示例:

注意SwipeBackLayout布局的孩子只能有一个

    <?xml version="1.0" encoding="utf-8"?>    <com.cxmscb.cxm.dragbackproject.SwipeBackLayout        android:id="@+id/dragBackLayout"        xmlns:android="http://schemas.android.com/apk/res/android"        android:layout_width="match_parent"        android:layout_height="match_parent">    <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"        xmlns:tools="http://schemas.android.com/tools"        android:layout_width="match_parent"        android:layout_height="match_parent"        android:background="#ffffff"        >        <TextView            android:layout_width="match_parent"            android:layout_height="56dp"            android:textColor="#ffffff"            android:textSize="20sp"            android:gravity="center"            android:background="#ef8789"            android:text="show"            android:id="@+id/textView"            android:layout_alignParentTop="true"            android:layout_alignParentLeft="true"            android:layout_alignParentStart="true" />    </RelativeLayout>    </com.cxmscb.cxm.dragbackproject.SwipeBackLayout>
  1. 为了在布局滑动时能看到之前的Activity界面,对Activity的主题进行设置半透明且无Titlebar

    android:theme="@android:style/Theme.Translucent.NoTitleBar"     
  2. 在activity中设计监听事件

    swipeBackLayout.setOnFinishScroll(new SwipeBackLayout.OnFinishScrollListener() {    @Override    public void complete() {        ShowActivity.this.finish();        Toast.makeText(ShowActivity.this,"finished",Toast.LENGTH_SHORT).show();    }})

完整项目代码地址

0 0
原创粉丝点击