随手一写就是一个侧滑关闭activity
剛忙完一段時間,今天剛清閑會,就把以前寫的東西整理整理。于是冥冥中發現有些東西完全可以共享出來,畢竟那么常見,而且簡單實用。
實現原因
其實側滑關閉activity在網上也有大量的文章去介紹他,我也有去看,要么是代碼實在太多看不下去,要么就是跑了項目沒有反應的。唯一的方法還是自己隨手魯一個~,側滑這個東西在android中是比較少見的,ios是最常見不過了,因為畢竟他們沒有物理返回鍵。還有UIScrollView那些。然而我們用的最多的QQ也只是有個功能,并沒有真正的滑動效果。至于微信的,我記得N久以前滑出了一個bug。也沒什么印象了。估計也是極小的概率事件。于是,當初我就強行的魯了一個。下面我們一步步分析實現的思路以及代碼。
百行代碼解決側滑關閉
首先來看下我們一些簡單的定義:
private Activity activity;private Scroller scroller;//上次ACTION_MOVE時的X坐標private int last_X;//屏幕寬度private int width;//可滑動的最小X坐標,小于該坐標的滑動不處理private int min_X;// 頁面邊緣的陰影圖private Drawable left_shodow;//頁面邊緣陰影的寬度默認值private static final int SHADOW_WIDTH = 16;// 頁面邊緣陰影的寬度private int shadow_width;// Activity finish標識符private boolean isFinish;這邊我已經注釋過了,就不做過多就寫了。接下來,我們看下我們的一些初始化已經外部調用方法:
private void initView(Activity activity) {this.activity = activity;scroller = new Scroller(activity);left_shodow = getResources().getDrawable(R.drawable.left_shadow);int density = (int) activity.getResources().getDisplayMetrics().density;shadow_width = SHADOW_WIDTH * density;// 這里你一定要設置成透明背景,不然會影響你看到底層布局setBackgroundColor(Color.argb(0, 0, 0, 0));}public void bindActivity(Activity activity) {ViewGroup decorView = (ViewGroup) activity.getWindow().getDecorView();View child = decorView.getChildAt(0);decorView.removeView(child);addView(child);decorView.addView(this);我們主要看下bindactivity這個方法。這個是我們用來綁定一個activity的。這個activity你們可以基于baseactivity實現一個backactivity。為什么要這么做,因為你每個activity都要寫這么一句話,我感覺就是浪費時間,一個基類直接解決。這個activity我們可以這么寫:
public abstract class SWBackActivity extends Activity {protected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);SWBackLayout layout = new SWBackLayout(this);layout.bindActivity(this);}protected abstract void afterInject();protected abstract void afterInitView();}那么接下來我們看下,如果對手勢的處理讓他側滑關閉呢?
public boolean onTouchEvent(MotionEvent event) {switch (event.getAction()) {case MotionEvent.ACTION_DOWN:last_X = (int) event.getX();width = getWidth();min_X = width / 10;break;case MotionEvent.ACTION_MOVE:int rightMovedX = last_X - (int) event.getX();if (getScrollX() + rightMovedX >= 0) {// 左側即將滑出屏幕scrollTo(0, 0);} else if ((int) event.getX() > min_X) {// 手指處于屏幕邊緣時不處理滑動scrollBy(rightMovedX, 0);}last_X = (int) event.getX();break;case MotionEvent.ACTION_UP:if (-getScrollX() < width / 3) {scrollBack();isFinish = false;} else {scrollClose();isFinish = true;}break;}return true;}private void scrollBack() {int startX = getScrollX();int dx = -getScrollX();scroller.startScroll(startX, 0, dx, 0, 300);invalidate();}private void scrollClose() {int startX = getScrollX();int dx = -getScrollX() - width;scroller.startScroll(startX, 0, dx, 0, 300);invalidate();}public void computeScroll() {if (scroller.computeScrollOffset()) {scrollTo(scroller.getCurrX(), 0);postInvalidate();} else if (isFinish) {activity.finish();}super.computeScroll();}protected void dispatchDraw(Canvas canvas) {super.dispatchDraw(canvas);drawShadow(canvas);}private void drawShadow(Canvas canvas) {// 保存畫布當前的狀態canvas.save();// 設置drawable的大小范圍left_shodow.setBounds(0, 0, shadow_width, getHeight());// 讓畫布平移一定距離canvas.translate(-shadow_width, 0);// 繪制Drawableleft_shodow.draw(canvas);// 恢復畫布的狀態canvas.restore();}首先我們在ACTION_DOWN記錄按下點的X坐標
然后在ACTION_MOVE中判斷,如果我們getScrollX() + rightMovedX是否是大于0的,如果大于0,表示Activity處于滑動狀態,并且是向左滑動,同時我們進行了判斷,手指處于屏幕邊緣時不可以滑動。
最后在ACTION_UP中判斷如果手指滑動的距離大于布局寬度的1/3,表示將Activity滑出界面,否則滑動到起始位置,我們利用Scroller類的startScroll()方法設置好開始位置,滑動距離和時間,然后調用postInvalidate()刷新界面,之后就到computeScroll()方法中,我們利用scrollTo()方法對該布局的父布局進行滾動,滾動結束之后,我們判斷界面是否滑出界面,如果是那就劃出頁面讓activity finish掉。否則,布局就歸位。
使用方法
其實使用方法很簡單,直接繼承SWBackActivity就可以了。那么我們最后來看下效果圖:
總結
以上是生活随笔為你收集整理的随手一写就是一个侧滑关闭activity的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: ROC曲线及如何计算AUC
- 下一篇: 柠檬 python 培训