SmartSwipe是一個(gè)Android側(cè)滑處理框架,它封裝了對(duì)控件側(cè)滑事件(上/下/左/右4個(gè)方向滑動(dòng)的手勢(shì)事件)的捕獲、分發(fā)及多點(diǎn)交替滑動(dòng)的處理,基于SmartSwipe我們可以為控件添加各種你想要的側(cè)滑效果。
創(chuàng)新互聯(lián)建站主營(yíng)康馬網(wǎng)站建設(shè)的網(wǎng)絡(luò)公司,主營(yíng)網(wǎng)站建設(shè)方案,重慶APP開(kāi)發(fā)公司,康馬h5小程序定制開(kāi)發(fā)搭建,康馬網(wǎng)站營(yíng)銷推廣歡迎康馬等地區(qū)企業(yè)咨詢先來(lái)看看它能做些什么吧!
如果已經(jīng)了解SmartSwipe的功能,只是想了解他的實(shí)現(xiàn)原理 可跳過(guò)第一節(jié),直接看第二節(jié)的原理介紹。 如果覺(jué)得文章還不錯(cuò),我會(huì)定期分享Android知識(shí)點(diǎn)及解析,還會(huì)不斷更新的BATJ面試專題,歡迎大家前來(lái)探討交流, 如有好的文章也歡迎投稿。
//仿手機(jī)QQ的手勢(shì)滑動(dòng)返回SmartSwipeBack.activityStayBack(application,?null);????? //仿微信帶聯(lián)動(dòng)效果的透明側(cè)滑返回SmartSwipeBack.activitySlidingBack(application,?null);?? //側(cè)滑開(kāi)門樣式關(guān)閉activitySmartSwipeBack.activityDoorBack(application,?null);????? //側(cè)滑百葉窗樣式關(guān)閉activitySmartSwipeBack.activityShuttersBack(application,?null);? //仿小米MIUI系統(tǒng)的貝塞爾曲線返回效果SmartSwipeBack.activityBezierBack(application,?null);
效果圖:
側(cè)滑返回效果
//為控件添加仿iOS的彈性留白效果://當(dāng)縱向不能滾動(dòng)(或滾動(dòng)到頂/底)時(shí),若繼續(xù)拖動(dòng),則UI呈現(xiàn)彈性留白效果,釋放后平滑恢復(fù)SmartSwipe.wrap(view) ????.addConsumer(new?SpaceConsumer()) ????.enableVertical();
效果圖:
//為控件添加仿MIUI的彈性拉伸效果://當(dāng)縱向不能滾動(dòng)(或滾動(dòng)到頂/底)時(shí),若繼續(xù)拖動(dòng),則UI呈現(xiàn)彈性拉伸效果,釋放后平滑恢復(fù)SmartSwipe.wrap(view) ????.addConsumer(new?StretchConsumer()) ????.enableVertical();
效果圖:
//xxxMode第二個(gè)參數(shù)為false,表示工作方向?yàn)榭v向:下拉刷新&上拉加載更多 //如果第二個(gè)參數(shù)設(shè)置為true,則表示工作方向?yàn)闄M向:右拉刷新&左拉加載更多 SmartSwipeRefresh.drawerMode(view,?false).setDataLoader(loader); SmartSwipeRefresh.behindMode(view,?false).setDataLoader(loader); SmartSwipeRefresh.scaleMode(view,?false).setDataLoader(loader); SmartSwipeRefresh.translateMode(view,?false).setDataLoader(loader);
樣式 | 效果圖 |
---|---|
drawerMode | drawerMode |
behindMode | behindMode |
scaleMode | scaleMode |
translateMode | translateMode |
SmartSwipe.wrap(view)??? //添加抽屜效果,其效果與DrawerLayout相似 ????//??DrawerLayout只支持左右2個(gè)方向,而DrawerConsumer支持上下左右4個(gè)方向 ????.addConsumer(new?DrawerConsumer())?? ????//設(shè)置橫向(左右兩側(cè))的抽屜為同一個(gè)view(常見(jiàn)的側(cè)滑顯示刪除按鈕的功能) ????.setHorizontalDrawerView(buttonsViewGroup)? ????.setScrimColor(0x2F000000)?//設(shè)置遮罩的顏色 ????.setShadowColor(0x80000000)?//設(shè)置邊緣的陰影顏色 ????;
效果圖:
SmartSwipe.wrap(view) ????.addConsumer(new?SlidingConsumer()) ????.setRelativeMoveFactor(0.3F)?//聯(lián)動(dòng)系數(shù) ????.setHorizontalDrawerView(buttonsView) ????.setScrimColor(0x2F000000) ????;
效果圖:
SmartSwipe.wrap(coverView) ????.addConsumer(new?ShuttersConsumer())?//百葉窗效果 ????.setScrimColor(0xAF000000) ????.enableAllDirections() ????.addListener(new?SimpleSwipeListener()?{????????@Override ????????public?void?onSwipeOpened(SmartSwipeWrapper?wrapper,?SwipeConsumer?consumer,?int?direction)?{????????????//封面打開(kāi)后自動(dòng)隱藏或移除 ????????????wrapper.setVisibility(View.GONE); ????????} ????});
效果圖:
SmartSwipe.wrap(coverView) ????.addConsumer(new?DoorConsumer())?//開(kāi)門效果 ????.setScrimColor(0xAF000000) ????.enableAllDirections() ????.addListener(new?SimpleSwipeListener()?{????????@Override ????????public?void?onSwipeOpened(SmartSwipeWrapper?wrapper,?SwipeConsumer?consumer,?int?direction)?{????????????//封面打開(kāi)后自動(dòng)隱藏或移除 ????????????wrapper.setVisibility(View.GONE); ????????} ????});
效果圖:
ViewDragHelper是Android官方支持庫(kù)中有一個(gè)工具類。它可以幫助我們處理控件的拖拽:先創(chuàng)建一個(gè)自定義ViewGroup,將被拖動(dòng)的控件添加到這個(gè)自定義ViewGroup中,并用ViewDragHelper來(lái)處理控件的拖拽。
ViewDragHelper的主要作用是:攔截父容器的touch事件,捕獲一個(gè)子控件來(lái)進(jìn)行拖拽,通過(guò)改變這個(gè)子控件的left和top來(lái)將其在父容器中重新定位,從而達(dá)到拖拽的效果。
在官方支持庫(kù)中,滑動(dòng)抽屜相關(guān)的SlidingPaneLayout和DrawerLayout,以及CoordinatorLayout布局相關(guān)的BottomSheetBehavior和SwipeDismissBehavior,都能看到ViewDragHelper的身影。
但是,ViewDragHelper的名稱也表明它就是用來(lái)處理拖拽的,拖拽的對(duì)象必須是一個(gè)子View,在拖拽的過(guò)程中需要改變子控件的left和top,對(duì)于一些沒(méi)有子View被拖拽的側(cè)滑效果(例如:MIUI系統(tǒng)的貝塞爾曲線側(cè)滑返回效果、手機(jī)QQ的側(cè)滑返回效果及MIUI官方app中的普遍使用了的彈性拉伸效果等等),卻有點(diǎn)力有不逮。
針對(duì)側(cè)滑這個(gè)手勢(shì),我們能不能將它的概念抽象一下,到底側(cè)滑指的是什么呢?
狹義側(cè)滑:從屏幕的某個(gè)邊緣開(kāi)始向著遠(yuǎn)離該邊緣的方向滑動(dòng)
廣義側(cè)滑:手指在屏幕上按下之后向著某個(gè)方向滑動(dòng)
我的理解是,廣義側(cè)滑包含狹義側(cè)滑,只不過(guò)是觸發(fā)區(qū)域是否在屏幕邊緣的區(qū)別罷了。
既然側(cè)滑手勢(shì)能被明確地抽象出來(lái),那么我們是否可以借鑒ViewDragHelper的事件攔截思路將它做這樣的封裝?
對(duì)被側(cè)滑控件的touch事件進(jìn)行攔截分析,確認(rèn)是否將其捕獲作為側(cè)滑手勢(shì) 然后計(jì)算好側(cè)滑的實(shí)時(shí)位移(手指滑動(dòng)的位移,而不是不依賴于View的left與top) 再通過(guò)策略模式(Strategy?Pattern)使用不同的策略不斷消費(fèi)側(cè)滑的位移來(lái)進(jìn)行側(cè)滑效果的UI呈現(xiàn)。
答案是肯定的!
SmartSwipe在ViewDragHelper的基礎(chǔ)上,將它對(duì)子View的捕獲及移動(dòng)處理改造成對(duì)父View自身觸摸事件的定性(能否及是否捕獲)、定向(捕獲的事件所觸發(fā)的側(cè)滑方向)及定位(事件捕獲之后在側(cè)滑方向上移動(dòng)的距離),并將側(cè)滑距離交由SwipeConsumer來(lái)消費(fèi),SwipeConsumer根據(jù)側(cè)滑距離的變化對(duì)控件布局進(jìn)行相應(yīng)的改變。
SmartSwipe的封裝思路如下:
用一個(gè)ViewGroup將需要處理側(cè)滑事件的控件View包裹起來(lái)(被包裹起來(lái)的控件作為它的contentView
)
可以為這個(gè)ViewGroup添加一些附屬控件(如:滑動(dòng)抽屜)
攔截這個(gè)ViewGroup的touch事件,并將touch事件轉(zhuǎn)換為側(cè)滑距離交給SwipeConsumer進(jìn)行消費(fèi)
SwipeConsumer根據(jù)側(cè)滑距離的變化對(duì)控件布局進(jìn)行相應(yīng)的改變
通過(guò)繼承SwipeConsumer,用不同的方式來(lái)改變控件布局(例如:對(duì)contentView
及附屬控件的位置、縮放、透明等進(jìn)行改變),從而實(shí)現(xiàn)各種側(cè)滑的效果。
于是,側(cè)滑的手勢(shì)事件識(shí)別及滑動(dòng)距離計(jì)算的工作在框架內(nèi)部就統(tǒng)一完成了,至于根據(jù)側(cè)滑距離來(lái)實(shí)現(xiàn)各種不同的UI呈現(xiàn)效果,就可以很方便地通過(guò)繼承SwipeConsumer來(lái)實(shí)現(xiàn)了。
以框架內(nèi)置的仿MIUI系統(tǒng)應(yīng)用中彈性拉伸效果的實(shí)現(xiàn)為例
根據(jù)側(cè)滑距離,對(duì)contentView進(jìn)行縮放和平移,從而實(shí)現(xiàn)彈性拉伸效果
代碼如下:
public?class?StretchConsumer?extends?SwipeConsumer?{ ????@Override ????public?void?onDetachFromWrapper()?{ ????????super.onDetachFromWrapper(); ????????View?contentView?=?mWrapper.getContentView(); ????????if?(contentView?!=?null)?{ ????????????contentView.setScaleX(1); ????????????contentView.setScaleY(1); ????????????contentView.setTranslationX(0); ????????????contentView.setTranslationY(0); ????????} ????} ????@Override ????public?void?onDisplayDistanceChanged(int?distanceXToDisplay, ????????int?distanceYToDisplay,?int?dx,?int?dy)?{ ????????View?contentView?=?mWrapper.getContentView(); ????????if?(contentView?!=?null)?{ ????????????if?(((distanceXToDisplay?>=?0)?&&?isLeftEnable())?|| ????????????????????((distanceXToDisplay?<=?0)?&&?isRightEnable()))?{ ????????????????contentView.setScaleX(1?+ ????????????????????(Math.abs((float)?distanceXToDisplay)?/?mWidth)); ????????????????contentView.setTranslationX(distanceXToDisplay?/?2F); ????????????} ????????????if?(((distanceYToDisplay?>=?0)?&&?isTopEnable())?|| ????????????????????((distanceYToDisplay?<=?0)?&&?isBottomEnable()))?{ ????????????????contentView.setScaleY(1?+ ????????????????????(Math.abs((float)?distanceYToDisplay)?/?mHeight)); ????????????????contentView.setTranslationY(distanceYToDisplay?/?2F); ????????????} ????????} ????} }
以上就是實(shí)現(xiàn)彈性拉伸效果的全部代碼,很簡(jiǎn)單,不是嗎?
它的使用方式同樣簡(jiǎn)單:
SmartSwipe.wrap(view)?//指定目標(biāo)控件 ????.addConsumer(new?StretchConsumer())?//添加彈性拉伸效果 ????.enableVertical();?//指定工作方向?yàn)椋荷?、?個(gè)方向
再來(lái)看看仿手機(jī)QQ側(cè)滑返回的效果如何實(shí)現(xiàn)
手機(jī)QQ側(cè)滑時(shí)UI沒(méi)有任何變化 在手指釋放時(shí),根據(jù)滑動(dòng)的方向和速率來(lái)決定是否finish當(dāng)前Activity
代碼如下:
public?class?StayConsumer?extends?SwipeConsumer?{ ????private?int?mMinVelocity?=?1000; ????public?StayConsumer()?{?//不能通過(guò)滑動(dòng)距離判斷是否需要打開(kāi) ????????setOpenDistance(Integer.MAX_VALUE).setMaxSettleDuration(0);?//打開(kāi)時(shí)無(wú)需動(dòng)畫,時(shí)間置為0 ????} ????@Override ????protected?void?onDisplayDistanceChanged(int?distanceXToDisplay, ????????int?distanceYToDisplay,?int?dx,?int?dy)?{?//滑動(dòng)時(shí)不需要對(duì)contentView做任何改變 ????} ????@Override ????public?void?onSwipeReleased(float?xVelocity,?float?yVelocity)?{?//在釋放時(shí),根據(jù)速率和方向來(lái)決定是否打開(kāi) ????????if?(Math.abs(xVelocity)?>?Math.abs(yVelocity))?{ ????????????if?(((mDirection?==?DIRECTION_LEFT)?&&?(xVelocity?>=?mMinVelocity))?|| ????????????????????((mDirection?==?DIRECTION_RIGHT)?&& ????????????????????(xVelocity?<=?-mMinVelocity)))?{?//置為打開(kāi)狀態(tài) ????????????????mCurSwipeDistanceX?=?getSwipeOpenDistance(); ????????????????mProgress?=?1; ????????????} ????????}?else?{ ????????????if?(((mDirection?==?DIRECTION_TOP)?&&?(yVelocity?>=?mMinVelocity))?|| ????????????????????((mDirection?==?DIRECTION_BOTTOM)?&& ????????????????????(yVelocity?<=?-mMinVelocity)))?{?//置為打開(kāi)狀態(tài) ????????????????mCurSwipeDistanceY?=?getSwipeOpenDistance(); ????????????????mProgress?=?1; ????????????} ????????} ????????super.onSwipeReleased(xVelocity,?yVelocity); ????} ????public?int?getMinVelocity()?{ ????????return?mMinVelocity; ????}?//支持使用者設(shè)置最低速率的閾值 ????public?StayConsumer?setMinVelocity(int?minVelocity)?{ ????????if?(minVelocity?>?0)?{ ????????????this.mMinVelocity?=?minVelocity; ????????} ????????return?this; ????} }
是不是也很簡(jiǎn)單!
碼字不易,如果覺(jué)得文章還不錯(cuò)的朋友點(diǎn)贊+關(guān)注+轉(zhuǎn)發(fā),我會(huì)定期分享Android知識(shí)點(diǎn)及解析,還會(huì)不斷更新的BATJ面試專題以及互聯(lián)網(wǎng)趣事,歡迎大家前來(lái)探討交流,如有好的文章也歡迎投稿。
另外有需要云服務(wù)器可以了解下創(chuàng)新互聯(lián)scvps.cn,海內(nèi)外云服務(wù)器15元起步,三天無(wú)理由+7*72小時(shí)售后在線,公司持有idc許可證,提供“云服務(wù)器、裸金屬服務(wù)器、高防服務(wù)器、香港服務(wù)器、美國(guó)服務(wù)器、虛擬主機(jī)、免備案服務(wù)器”等云主機(jī)租用服務(wù)以及企業(yè)上云的綜合解決方案,具有“安全穩(wěn)定、簡(jiǎn)單易用、服務(wù)可用性高、性價(jià)比高”等特點(diǎn)與優(yōu)勢(shì),專為企業(yè)上云打造定制,能夠滿足用戶豐富、多元化的應(yīng)用場(chǎng)景需求。
網(wǎng)站標(biāo)題:你見(jiàn)過(guò)微信側(cè)滑返回的聯(lián)動(dòng)效果,但開(kāi)門效果、百葉窗效果見(jiàn)過(guò)嗎?-創(chuàng)新互聯(lián)
URL網(wǎng)址:http://aaarwkj.com/article38/ppgsp.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供網(wǎng)站內(nèi)鏈、域名注冊(cè)、建站公司、云服務(wù)器、響應(yīng)式網(wǎng)站、自適應(yīng)網(wǎng)站
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來(lái)源: 創(chuàng)新互聯(lián)
猜你還喜歡下面的內(nèi)容