1直想自己实现Activity的侧滑烧毁,无奈在finish activity的时候遇到了瓶颈。今天看到1个开源库,那哥们把Activity的背景设置成了透明,这才恍然大悟。这里share1下。
大体思路讲授:
知识储备:
贴出核心类
public class SlidingFinishLayout extends FrameLayout {
private Scroller mScroller;
private int mTouchSlop;
private ViewGroup parentView;
private int screenWidth;
private int last_x;
private int last_y;
private int delay_x;
private int delay_y;
private boolean isFinish = false;
private Activity mActivity;
private SlidingFinishLayout.OnActivityFinishListener onActivityFinish;
public SlidingFinishLayout(Context context, AttributeSet attrs) {
super(context, attrs);
mScroller = new Scroller(context);
mTouchSlop = ViewConfiguration.get(context).getScaledTouchSlop();
}
public void attachActivity(Activity activity) {
this.mActivity = activity;
}
public void detachActivity() {
if (this.mActivity != null) {
mActivity = null;
}
}
@Override
protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
super.onLayout(changed, left, top, right, bottom);
if (changed) {
ViewGroup decor = (ViewGroup) mActivity.getWindow().getDecorView();
mActivity.getWindow().setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));
mActivity.getWindow().getDecorView().setBackgroundColor(Color.TRANSPARENT);
View decorChild = decor.findViewById(android.R.id.content);
while (decorChild.getParent() != decor) {
decorChild = (View) decorChild.getParent();
}
parentView = decor;
screenWidth = getWidth();
}
}
/**
* 进行事件拦截
*
* @param ev
* @return
*/
@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
boolean isIntercept = false;
switch (ev.getAction()) {
case MotionEvent.ACTION_DOWN:
last_x = (int) ev.getRawX();
last_y = (int) ev.getRawY();
break;
case MotionEvent.ACTION_MOVE:
int current_x = (int) ev.getRawX();
int current_y = (int) ev.getRawY();
delay_x = current_x - last_x;
delay_y = current_y - last_y;
if ((Math.abs(delay_x) / (Math.abs(delay_y) + 1) >= 2)) { //30度角的时候才开始拦截事件
isIntercept = true;
}
break;
case MotionEvent.ACTION_UP:
break;
}
return isIntercept;
}
/**
* 进行事件处理
*
* @param ev
* @return
*/
@Override
public boolean onTouchEvent(MotionEvent ev) {
switch (ev.getAction()) {
case MotionEvent.ACTION_DOWN:
last_x = (int) ev.getRawX();
last_y = (int) ev.getRawY();
break;
case MotionEvent.ACTION_MOVE:
int current_x = (int) ev.getRawX();
int current_y = (int) ev.getRawY();
delay_x = current_x - last_x;
delay_y = current_y - last_y;
if (Math.abs(delay_x) > mTouchSlop) {
if ((Math.abs(delay_x) / (Math.abs(delay_y) + 1) >= 2)) { //30度角的时候才开始处理事件
parentView.scrollBy(-delay_x, 0); //开始滑动
} else {
return false;
}
} else {
return false;
}
last_x = current_x;
last_y = current_y;
break;
case MotionEvent.ACTION_UP:
if (Math.abs(parentView.getScrollX()) > (screenWidth / 3)) { //如果滑动距离超越屏幕3分之1,则进行滑动烧毁,否则恢复原位
scrollFinish();
} else {
scrollOriginal();
}
break;
}
return true;
}
/**
* 滑动烧毁
*/
private void scrollFinish() {
final int delta = (screenWidth + parentView.getScrollX());
mScroller.startScroll(parentView.getScrollX(), 0, -delta + 1, 0);
postInvalidate();
isFinish = true;
}
/**
* 恢复到原始状态
*/
private void scrollOriginal() {
mScroller.startScroll(parentView.getScrollX(), 0, -parentView.getScrollX(), 0);
postInvalidate();
isFinish = false;
}
/**
* Activity烧毁的时候通知回调
*
* @param onActivityFinish
*/
public void setOnActivityFinishListener(SlidingFinishLayout.OnActivityFinishListener onActivityFinish) {
this.onActivityFinish = onActivityFinish;
}
@Override
public void computeScroll() {
if (mScroller.computeScrollOffset()) {
parentView.scrollTo(mScroller.getCurrX(), mScroller.getCurrY());
postInvalidate();
if (mScroller.isFinished() && isFinish) {
onActivityFinish.onActivityFinish();
}
}
}
在希望右滑烧毁的Activity中使用
public class SlideFinishActivity extends AppCompatActivity implements SlidingFinishLayout.OnActivityFinishListener {
SlidingFinishLayout sf_test;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_slide_finish);
sf_test = (SlidingFinishLayout) findViewById(R.id.sf_test);
sf_test.setOnActivityFinishListener(this); //设置烧毁的监听器
sf_test.attachActivity(this);
}
@Override
protected void onDestroy() {
super.onDestroy();
sf_test.detachActivity();
}
@Override
public void onActivityFinish() {
finish();
}
}
注意,该Activity的Style文件应当加入下面代码才可以生效 android:windowIsTranslucent。本代码是把Activity设置成透明状态
收工。
项目源码:https://github.com/WillSprint/SlideFinish
推荐1个侧滑库,本博客中的1些思想来源于该作者
https://github.com/Jude95/SwipeBackHelper