public class SwipeBackLayout extends SlidingPaneLayout {
private static final String TAG = SwipeBackLayout.class.getSimpleName();
private boolean supportSwipeBack = true;
private int maxEdgeDistance = 150;
public SwipeBackLayout(@NonNull Context context) {
super(context);
initMaxEdgeDistance(context);
}
public SwipeBackLayout(@NonNull Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
initMaxEdgeDistance(context);
}
public SwipeBackLayout(@NonNull Context context, @Nullable AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
initMaxEdgeDistance(context);
}
private void initMaxEdgeDistance(Context context) {
maxEdgeDistance = Math.round(TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 36f, context.getResources().getDisplayMetrics()));
}
@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
//如果不支持 滑动返回 不拦截
//拦截之后就会交给自己的 onTouchEvent
if (!supportSwipeBack) {
return false;
}
//按下的范围不在左边的范围之内,不拦截继续向下分发
if (shouldNotSwipeBack(ev)) {
Log.i(TAG, "onInterceptTouchEvent: 不拦截");
return false;
}
//父类返回true,表示拦截此事件
return super.onInterceptTouchEvent(ev);
}
/**
* 不拦截并不意味着不会传递到它的onTouchEvent
* 如果它的所有的子view 都不处理,还是会进入它
* 的onTouchEvent,所以shouldNotSwipeBack(ev) 判断
* 是必须的,因为SlidingPaneLayout 会返回true
* */
@Override
public boolean onTouchEvent(MotionEvent ev) {
/**actionDown事件返回false 之后后续事件不再传递给它*/
if (shouldNotSwipeBack(ev)) {
Log.i(TAG, "onTouchEvent: 我没有拦截但是我一样进来了");
return false;
}
return super.onTouchEvent(ev);
}
/**
* 判断是否需要滑动返回
* 只有在左边maxEdgeDistance 范围之内才能出发滑动返回
*/
private boolean shouldNotSwipeBack(MotionEvent motionEvent) {
return (this.supportSwipeBack) && (motionEvent != null)
&& (motionEvent.getAction() == MotionEvent.ACTION_DOWN)
&& (motionEvent.getX() > this.maxEdgeDistance);
}
public void setSupportSwipeBack(boolean supportSwipeBack) {
this.supportSwipeBack = supportSwipeBack;
}
public void setMaxEdgeDistance(int maxEdgeDistance) {
this.maxEdgeDistance = maxEdgeDistance;
}
}
public class SwipeBackActivityHelper {
private SwipeBackLayout swipeBackLayout;
public SwipeBackLayout getSwipeBackLayout() {
return swipeBackLayout;
}
public void initSwipeBackLayout(Activity activity, SlidingPaneLayout.PanelSlideListener listener) {
if (activity != null && activity.getWindow() != null) {
this.swipeBackLayout = new SwipeBackLayout(activity);
try {
/**滑动面板距离右边的最小距离*/
Field overhangsize = SlidingPaneLayout.class.getDeclaredField("mOverhangSize");
overhangsize.setAccessible(true);
overhangsize.set(swipeBackLayout, 0);
} catch (NoSuchFieldException | IllegalAccessException e) {
e.printStackTrace();
}
this.swipeBackLayout.setPanelSlideListener(listener);
this.swipeBackLayout.setSliderFadeColor(Color.argb(10, 00, 00, 00));
this.swipeBackLayout.setShadowResourceLeft(R.drawable.swipe_back_shadow);
}
}
public void setSwipeBackContentView(Activity activity, View content, ViewGroup.LayoutParams layoutParams, boolean setBakcGround) {
Window window = activity.getWindow();
Drawable windowBg = window.getDecorView().getBackground();
//将window 的背景设置为透明,以便滑动的时候能看到下面的activity
window.setBackgroundDrawable(new ColorDrawable(Color.argb(10, 00, 00, 00)));
View leftView = new View(activity);
leftView.setLayoutParams(new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT));
this.swipeBackLayout.addView(leftView, 0);
if (setBakcGround) {
//将content设置为原来设置的背景
content.setBackground(windowBg);
}
if (layoutParams != null) {
this.swipeBackLayout.addView(content, 1, layoutParams);
} else {
this.swipeBackLayout.addView(content, 1);
}
}
public void setSupportSwipeBack(boolean swipeBack) {
if (swipeBackLayout != null) {
swipeBackLayout.setSupportSwipeBack(swipeBack);
}
}
public void closePanel() {
if (swipeBackLayout != null) {
swipeBackLayout.closePane();
}
}
}
public class BaseSwipeBackActivity extends AppCompatActivity {
private static final String TAG = BaseSwipeBackActivity.class.getSimpleName();
private SwipeBackActivityHelper mSwipeBack;
private SlidingPaneLayout.PanelSlideListener panelSlideListener = new SlidingPaneLayout.PanelSlideListener() {
private boolean panelClosed = true;
@Override
public void onPanelSlide(@NonNull View view, float offset) {
Log.i(TAG, "onPanelSlide: offset = " + offset);
if (panelClosed && offset > 0) {
panelClosed = false;
view.post(new Runnable() {
@Override
public void run() {
onSwipeBackStarted();
}
});
}
if (offset == 0) {
panelClosed = true;
view.post(new Runnable() {
@Override
public void run() {
onSwipeBackCanceled();
}
});
}
}
@Override
public void onPanelOpened(@NonNull View view) {
Log.i(TAG, "onPanelOpened: ");
onSwipeBack();
}
@Override
public void onPanelClosed(@NonNull View view) {
Log.i(TAG, "onPanelClosed: ");
if (panelClosed) {
return;
}
panelClosed = true;
view.post(new Runnable() {
@Override
public void run() {
onSwipeBackCanceled();
}
});
}
};
private void initSwipeBack() {
this.mSwipeBack = new SwipeBackActivityHelper();
this.mSwipeBack.initSwipeBackLayout(this, this.panelSlideListener);
}
protected boolean isSetBackground() {
return true;
}
protected boolean isSupportSwipeBack() {
return true;
}
protected void onSwipeBack() {
finish();
/* if (isSupportSwipeBack()) {
overridePendingTransition(0, R.anim.activity_slide_out_right_finish);
}*/
}
protected void onSwipeBackCanceled() {
}
protected void onSwipeBackStarted() {
@SuppressLint("WrongConstant")
InputMethodManager inputMethodManager = (InputMethodManager) getSystemService("input_method");
View view = getCurrentFocus();
if (view != null) {
inputMethodManager.hideSoftInputFromWindow(view.getWindowToken(), InputMethodManager.HIDE_NOT_ALWAYS);
}
}
public void setContentView(@LayoutRes int resLayout) {
if (isSupportSwipeBack()) {
initSwipeBack();
}
View contentView;
if ((this.mSwipeBack != null) && (this.mSwipeBack.getSwipeBackLayout() != null)) {
contentView = LayoutInflater.from(this).inflate(resLayout, null);
this.mSwipeBack.setSwipeBackContentView(this, contentView, null, isSetBackground());
super.setContentView(this.mSwipeBack.getSwipeBackLayout());
} else {
contentView = LayoutInflater.from(this).inflate(resLayout, null);
super.setContentView(contentView);
}
}
public void setContentView(View contentView) {
if (isSupportSwipeBack()) {
initSwipeBack();
}
if ((this.mSwipeBack != null) && (this.mSwipeBack.getSwipeBackLayout() != null)) {
this.mSwipeBack.setSwipeBackContentView(this, contentView, null, isSetBackground());
super.setContentView(this.mSwipeBack.getSwipeBackLayout());
} else {
super.setContentView(contentView);
}
}
public void setContentView(View contentView, ViewGroup.LayoutParams layoutParams) {
if (isSupportSwipeBack()) {
initSwipeBack();
}
if ((this.mSwipeBack != null) && (this.mSwipeBack.getSwipeBackLayout() != null)) {
this.mSwipeBack.setSwipeBackContentView(this, contentView, layoutParams, isSetBackground());
super.setContentView(this.mSwipeBack.getSwipeBackLayout() );
} else {
super.setContentView(contentView);
}
}
protected void setSupportSwipeBack(boolean supportSwipeBack) {
if (this.mSwipeBack != null) {
this.mSwipeBack.setSupportSwipeBack(supportSwipeBack);
}
}
protected void swipeToNormal() {
if ((isSupportSwipeBack()) && (this.mSwipeBack != null)) {
this.mSwipeBack.closePanel();
}
}
}
总结:算是对事件分发的复习吧