国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 系統(tǒng) > Android > 正文

Android滑動優(yōu)化高仿QQ6.0側(cè)滑菜單(滑動優(yōu)化)

2020-04-11 10:51:30
字體:
供稿:網(wǎng)友

 推薦閱讀Android使用ViewDragHelper實現(xiàn)仿QQ6.0側(cè)滑界面(一)

但是之前的實現(xiàn),只是簡單的可以顯示和隱藏左側(cè)的菜單,但是特別生硬,而且沒有任何平滑的趨勢,那么今天就來優(yōu)化一下吧,加上平滑效果,而且可以根據(jù)手勢滑動的方向來判斷是否是顯示和隱藏。

首先先來實現(xiàn)手勢判斷是否隱藏和顯示

這里就要用到了一個方法了,如下:

這個是ViewDradHelper里面的方法:

/*** 當view被釋放的時候處理的事情(松手)** @param releasedChild 被釋放的子view* @param xvel 水平方向的速度 幀每秒 向右為 +* @param yvel 豎直方向的速度 向下為 +*/@Overridepublic void onViewReleased(View releasedChild, float xvel, float yvel) {Log.d("DragLayout", "xvel : " + xvel + " yvel :" + yvel);super.onViewReleased(releasedChild, xvel, yvel);//判斷關(guān)閉和打開//在這里我們首先判斷什么時候打開,然后剩下的都是關(guān)閉狀態(tài)//首先是我的主面板的左側(cè)具體屏幕左側(cè)已經(jīng)大于mRange/2的距離并且右滑的速度大于0,此時打開if (xvel >= 0 && mMainContent.getLeft() > mRange / 2.0f) {open();} else if (xvel > 0) {//第二種就是我右滑的速度大于0(這里的速度自己定義哈,根據(jù)自己想要實現(xiàn)的敏感度)open();} else {//剩余的所有情況都是關(guān)閉close();}}

close()方法(DragLayout里面的方法):

/*** 關(guān)閉*/public void close() {int finalLeft = 0;//調(diào)用layout方法,擺放主布局/*** @param l Left position, relative to parent* @param t Top position, relative to parent* @param r Right position, relative to parent* @param b Bottom position, relative to parent*/mMainContent.layout(finalLeft, 0, finalLeft + mWidth, finalLeft + mHeight);}

open()方法(DragLayout里面的方法):

/*** 打開*/public void open() {int finalLeft = mRange;mMainContent.layout(finalLeft, 0, finalLeft + mWidth, finalLeft + mHeight);}

這個是否就可以實現(xiàn)根據(jù)手勢來判斷是否打開和關(guān)閉了。

接下來我們就來實現(xiàn)如何平滑的關(guān)閉和打開,話不多說,代碼說話(這里對上面的open和close做了一些處理):

public void close() {close(true);}/*** 關(guān)閉** @param isSmooth 是否平滑的關(guān)閉*/public void close(boolean isSmooth) {int finalLeft = 0;if (isSmooth) {/*** public boolean smoothSlideViewTo(View child, int finalLeft, int finalTop)方法的解釋** Animate the view <code>child</code> to the given (left, top) position.* If this method returns true, the caller should invoke {@link #continueSettling(boolean)}* on each subsequent frame to continue the motion until it returns false. If this method* returns false there is no further work to do to complete the movement.** 返回true 代表還沒有移動到指定的位置,需要刷新界面,繼續(xù)移動* 返回false 就停止工作哈*///1、觸發(fā)動畫if (mDragHelper.smoothSlideViewTo(mMainContent, finalLeft, 0)) {//參數(shù)傳this,也就是child所在的viewgroupViewCompat.postInvalidateOnAnimation(this);}} else {//調(diào)用layout方法,擺放主布局/*** @param l Left position, relative to parent* @param t Top position, relative to parent* @param r Right position, relative to parent* @param b Bottom position, relative to parent*/mMainContent.layout(finalLeft, 0, finalLeft + mWidth, finalLeft + mHeight);}}/*** 打開*/public void open(boolean isSmooth) {int finalLeft = mRange;if (isSmooth && mDragHelper.smoothSlideViewTo(mMainContent, finalLeft, 0)) {//參數(shù)傳this,也就是child所在的viewgroupViewCompat.postInvalidateOnAnimation(this);} else {mMainContent.layout(finalLeft, 0, finalLeft + mWidth, finalLeft + mHeight);}}public void open() {open(true);}

來看下效果圖吧(里面的白道問題是錄屏導(dǎo)致,運行的沒有這個哈):

這里寫圖片描述

這個時候,基本上差不多了,剩下的,我們就來添加一些狀態(tài)和設(shè)置listener的方法,留給外面的調(diào)用吧。,代碼很簡單:

/*** 定義當前狀態(tài) 默認是關(guān)閉狀態(tài)*/private Status mStatus = Status.CLOSE;/*** 狀態(tài)枚舉* 關(guān)閉 CLOSE* 打開 OPEN* 拖拽 DRAGING*/public enum Status {CLOSE, OPEN, DRAGING;}private OnDragStatusListener mListener;public void setDragStateListener(OnDragStatusListener listener) {mListener = listener;}public interface OnDragStatusListener {/*** 關(guān)閉邏輯*/void onClose();/*** 打開邏輯*/void onOpen();/*** 拖拽邏輯** @param percent*/void onDraging(float percent);}

狀態(tài)更新,方法調(diào)用,這個dispatchDragEvent()在onViewPositionChanged()這個方法中調(diào)用一下就行,因為拖拽的時候狀態(tài)時刻在變化,所以我們在這個方法中調(diào)用:

/*** 狀態(tài)更新方法執(zhí)行* * @param newLeft*/private void dispatchDragEvent(int newLeft) {//得到的一個百分比float percent = newLeft * 1.0f / mRange;//0.0f--->1.0fLog.d("DragLayout", "percent : " + percent);if (mListener != null) {mListener.onDraging(percent);}//跟新狀態(tài)執(zhí)行回調(diào)Status lastStatus = mStatus;mStatus = updateStatus(percent);if (mStatus != lastStatus) {//狀態(tài)發(fā)生變化if (mStatus == Status.CLOSE) {//當前狀態(tài)是關(guān)閉if (mListener != null) {mListener.onClose();}} else if (mStatus == Status.OPEN) {if (mListener != null) {mListener.onOpen();}}}}/*** 狀態(tài)更新方法** @param percent* @return*/private Status updateStatus(float percent) {if (percent == 0) {return Status.CLOSE;} else if (percent == 1) {return Status.OPEN;}return Status.DRAGING;}

好了,到此為止,高仿QQ6.0側(cè)滑基本完成,下面我們來看下效果吧。

這里寫圖片描述 

好了,這個側(cè)滑就這樣完成了,后期會加在主頁中加入listview(嘗試用RecycleView)實現(xiàn)左滑刪除效果,現(xiàn)在附上該demo的地址,后期添加的也會更新至此。

發(fā)表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發(fā)表
主站蜘蛛池模板: 罗城| 枣阳市| 阿拉善右旗| 北碚区| 陆良县| 杭锦后旗| 青神县| 武功县| 石台县| 博湖县| 景泰县| 金门县| 抚州市| 南京市| 民权县| 荆州市| 苗栗县| 萍乡市| 镇原县| 东至县| 临湘市| 伊吾县| 明溪县| 革吉县| 威宁| 南投县| 梧州市| 太康县| 上犹县| 左云县| 日喀则市| 如皋市| 洱源县| 浏阳市| 保康县| 安宁市| 辰溪县| 灵宝市| 瑞昌市| 化德县| 同德县|