效果:

演示
核心思想:
- 自定义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));
}
}
麻雀虽小五脏俱全,虽看似简单,但是功能都已经达到了,在此基础上稍稍改动即可做成微信那种视差特效的侧滑关闭了,本来打算做成那样的,可是这会儿有事,要出门了,见谅。
网友评论