1. 程式人生 > >Android 利用ViewDragHelper打造側滑關閉控制元件

Android 利用ViewDragHelper打造側滑關閉控制元件

效果:

演示

核心思想:

  • 自定義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));
    }
}

麻雀雖小五臟俱全,雖看似簡單,但是功能都已經達到了,在此基礎上稍稍改動即可做成微信那種視差特效的側滑關閉了,本來打算做成那樣的,可是這會兒有事,要出門了,見諒。