1直想自己實現(xiàn)Activity的側(cè)滑燒毀,無奈在finish activity的時候遇到了瓶頸。今天看到1個開源庫,那哥們把Activity的背景設(shè)置成了透明,這才恍然大悟。這里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();
}
}
/**
* 進(jìn)行事件攔截
*
* @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;
}
/**
* 進(jìn)行事件處理
*
* @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,則進(jìn)行滑動燒毀,否則恢復(fù)原位
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;
}
/**
* 恢復(fù)到原始狀態(tài)
*/
private void scrollOriginal() {
mScroller.startScroll(parentView.getScrollX(), 0, -parentView.getScrollX(), 0);
postInvalidate();
isFinish = false;
}
/**
* Activity燒毀的時候通知回調(diào)
*
* @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); //設(shè)置燒毀的監(jiān)聽器
sf_test.attachActivity(this);
}
@Override
protected void onDestroy() {
super.onDestroy();
sf_test.detachActivity();
}
@Override
public void onActivityFinish() {
finish();
}
}
注意,該Activity的Style文件應(yīng)當(dāng)加入下面代碼才可以生效 android:windowIsTranslucent。本代碼是把Activity設(shè)置成透明狀態(tài)
收工。
項目源碼:https://github.com/WillSprint/SlideFinish
推薦1個側(cè)滑庫,本博客中的1些思想來源于該作者
https://github.com/Jude95/SwipeBackHelper