Android 利用ViewDragHelper打造侧滑关闭控件

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/c__chao/article/details/82557375

效果:

演示

核心思想:

  • 自定义ViewGroup控件,利用ViewDragHelper让此控件拥有滑动功能。
  • 将此控件附加到每一个Activity。

代码很简单就不一一解释了,代码备注很详细,所以直接贴代码了:

import android.app.Activity;
import android.content.Context;
import android.support.annotation.NonNull;
import android.support.v4.widget.ViewDragHelper;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.widget.FrameLayout;

import view.peakchao.view.R;

/**
 * 基于ViewDragHelper的侧滑关闭View
 * Created by Chao on 2018-09-09.
 */

public class SwipeBackLayout extends FrameLayout {
    private ViewDragHelper mHelper;
    private Activity mActivity;
    private View mView;

    public SwipeBackLayout(@NonNull Context context) {
        super(context);
        initViewDragHelper();
    }


    /**
     * 绑定 Activity
     *
     * @param activity 容器 Activity
     */
    public void attachActivity(Activity activity) {
        mActivity = activity;
        ViewGroup decor = (ViewGroup) activity.getWindow().getDecorView();
        View content = decor.getChildAt(0);
        decor.removeView(content);
        mView = content;
        addView(content);
        decor.addView(this);
    }

    /**
     * 初始化方法
     */
    private void initViewDragHelper() {
        mHelper = ViewDragHelper.create(this, 1.0f, new ViewDragHelper.Callback() {
            @Override
            public boolean tryCaptureView(View child, int pointerId) {
                // 默认不扑获 View
                return false;
            }

            @Override
            public int clampViewPositionHorizontal(View child, int left, int dx) {
                // 拖动限制(大于左边界)
                return Math.max(0, left);
            }

            @Override
            public int clampViewPositionVertical(View child, int top, int dy) {
                //左右侧滑时,限制不能上下拖动。
                return 0;
            }

            @Override
            public void onViewReleased(View releasedChild, float xvel, float yvel) {
                // 拖动距离大于屏幕的一半右移,拖动距离小于屏幕的一半左移
                int left = releasedChild.getLeft();
                if (left > getWidth() / 2) {
                    if (mActivity != null) {
                        mActivity.finish();
                        mActivity.overridePendingTransition(0, R.anim.right_out);
                    }
                } else {
                    mHelper.settleCapturedViewAt(0, 0);
                }
                invalidate();
            }

            @Override
            public void onEdgeDragStarted(int edgeFlags, int pointerId) {
                // 移动子 View
                mHelper.captureChildView(mView, pointerId);
            }
        });
        // 跟踪左边界拖动
        mHelper.setEdgeTrackingEnabled(ViewDragHelper.EDGE_LEFT);
    }


    @Override
    public boolean onInterceptTouchEvent(MotionEvent ev) {
        // 拦截代理
        return mHelper.shouldInterceptTouchEvent(ev);
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        // Touch Event 代理
        mHelper.processTouchEvent(event);
        return true;
    }

    @Override
    public void computeScroll() {
        // 子 View 需要更新状态
        if (mHelper.continueSettling(true)) {
            invalidate();
        }
    }

}

编写公共父类,或者将此类下面代码添加到需要侧滑关闭的Activity即可:

import android.content.Intent;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v7.app.AppCompatActivity;
import android.view.View;

import view.peakchao.view.R;
import view.peakchao.view.view.SwipeBackLayout;

/**
 * Created by Chao on 2018-09-09.
 */

public class SwipeActivity extends AppCompatActivity {
    private SwipeBackLayout mSwipeBackLayout;

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_swipe);//如果此类作为基类,这里layout需要从子类获取
        mSwipeBackLayout = new SwipeBackLayout(this);
    }

    @Override
    protected void onPostCreate(@Nullable Bundle savedInstanceState) {
        super.onPostCreate(savedInstanceState);
        mSwipeBackLayout.attachActivity(this);
    }

    public void start(View view) {
        startActivity(new Intent(this, SwipeActivity.class));
    }
}

麻雀虽小五脏俱全,虽看似简单,但是功能都已经达到了,在此基础上稍稍改动即可做成微信那种视差特效的侧滑关闭了,本来打算做成那样的,可是这会儿有事,要出门了,见谅。

猜你喜欢

转载自blog.csdn.net/c__chao/article/details/82557375