仿微信滑動(dòng)返回贿肩,實(shí)現(xiàn)背景聯(lián)動(dòng)(一峦椰、原理)

iOS應(yīng)用有一個(gè)普遍的功能——滑動(dòng)返回,手指從左邊緣向右滑動(dòng)汰规,手指松開時(shí)到達(dá)一定條件汤功,返回上層界面。在Android系統(tǒng)中溜哮,微信和簡(jiǎn)書也實(shí)現(xiàn)了這樣的功能滔金。網(wǎng)上有一些開源庫色解,也實(shí)現(xiàn)了滑動(dòng)返回部宿,用的時(shí)候不很滿足需求惊科,像沒有背景聯(lián)動(dòng);而且由于需要繼承滑動(dòng)返回基類算灸,破壞原項(xiàng)目的繼承關(guān)系忿族。

先來看看微信的效果:


weixin.gif

下面是我實(shí)現(xiàn)的锣笨,有木有感覺效果都達(dá)到了O(∩_∩)O~~,這是在項(xiàng)目中的應(yīng)用效果

1.gif

源碼地址:https://github.com/jinxiyang/SwipeBackLibrary

滑動(dòng)返回原理

滑動(dòng)返回的實(shí)現(xiàn)方式肠阱,并不我想出來的票唆,我只是站在了巨人的肩膀上,優(yōu)化他人的實(shí)現(xiàn)方式屹徘,再添加上自己的理解才寫出了這個(gè)項(xiàng)目走趋。文末列出參考的博客和代碼,在此表示由衷的感謝噪伊。

層級(jí)界面.png

如上圖所示簿煌,APP應(yīng)用的界面是一層一層的,A在最底層鉴吹,A上面有B姨伟,B上面有C,……豆励,D在最頂層夺荒。滑動(dòng)返回原理,其實(shí)就是監(jiān)聽手指在屏幕上的滑動(dòng)手勢(shì)良蒸,移動(dòng)頂層界面和下一層界面技扼。當(dāng)手指從屏幕左邊緣開始向右滑動(dòng)時(shí),使頂層界面(例如D)透明嫩痰;隨著手指向右滑動(dòng)剿吻,向右移動(dòng)頂層界面D,則左邊就會(huì)空出來串纺,進(jìn)而看到下一層的界面丽旅;當(dāng)松開手指時(shí),移動(dòng)的距離超過一定的閾值纺棺,觸發(fā)頂層界面D的銷毀榄笙,C界面的顯示出來。

怎么樣祷蝌,原理是不是很簡(jiǎn)單办斑。下圖是滑動(dòng)返回的示意圖:

滑動(dòng)返回示意圖.png

難點(diǎn)

是的,原理很簡(jiǎn)單,但實(shí)現(xiàn)起來卻有幾個(gè)難點(diǎn)乡翅。理想很美好,現(xiàn)實(shí)很殘酷罪郊。

  • 對(duì)于界面蠕蚜,可能是Activity(這里指DecorView),也可能是Fragment(這里指fragment.getView())悔橄,那頂層和下層界面就有好幾種情況了靶累。

  • 怎么樣監(jiān)聽手勢(shì)滑動(dòng),會(huì)不會(huì)和界面中的滑動(dòng)控件產(chǎn)生沖突癣疟。

  • 怎樣實(shí)現(xiàn)頂層界面透明挣柬,在滑動(dòng)時(shí)顯示下層界面,以及下層界面的聯(lián)動(dòng)睛挚。

  • 當(dāng)項(xiàng)目中已經(jīng)有一套自己定義的轉(zhuǎn)場(chǎng)動(dòng)畫邪蛔,當(dāng)滑動(dòng)到一定的閾值銷毀頂層界面時(shí),如何處理轉(zhuǎn)場(chǎng)動(dòng)畫扎狱。

  • 如何以最小的侵入性嵌入已有的項(xiàng)目侧到,而不改變?cè)械睦^承關(guān)系,而不大改動(dòng)原有代碼淤击。

  • 滑動(dòng)返回的Android版本兼容性匠抗。

好在是站在巨人的肩膀上,這些前人已經(jīng)都有解決方案污抬,我們不必重復(fù)造輪子汞贸,我們只需要整理并優(yōu)化,寫出一套符合需求的代碼印机。話說難點(diǎn)這么多矢腻,有什么方案可以解決呢?且聽我娓娓道來耳贬。

1踏堡、 難點(diǎn)一:
對(duì)于界面,可能是Activity(這里指DecorView)咒劲,也可能是Fragment(這里指fragment.getView())顷蟆,那頂層和下層界面就有好幾種情況了。

分析:仔細(xì)想一下腐魂,也就兩種情況:

  • 當(dāng)上下兩層界面都在同一activity內(nèi)時(shí)帐偎,頂層是Fragment,下層也是Fragment蛔屹。
  • 當(dāng)上下兩層界面不在同一activity內(nèi)時(shí)削樊,頂層應(yīng)該最多有一個(gè)Fragment,那頂層界面是activity,下層界面是activity漫贞。

因此可知滑動(dòng)返回甸箱,就是發(fā)生在Fragment和Fragment之間、activity和activity之間迅脐。

2芍殖、 難點(diǎn)二:
怎么樣監(jiān)聽手勢(shì)滑動(dòng),會(huì)不會(huì)和界面中的滑動(dòng)控件產(chǎn)生沖突谴蔑。

分析:Android提供了ViewDragHelper這個(gè)類豌骏,專門用來處理手勢(shì)拖動(dòng)事件的,廣泛的應(yīng)用于自定義ViewGroup的過程中隐锭,像Navigation Drawer的邊緣滑動(dòng)等窃躲。在這里我們用它來監(jiān)聽用戶的手勢(shì)拖動(dòng),捕獲指定的View钦睡,設(shè)置頂層界面的位置蒂窒,移動(dòng)背景界面的位置,實(shí)現(xiàn)頂層界面隨著手指而移動(dòng)赎婚,背景界面聯(lián)動(dòng)刘绣。后面源碼分析,具體介紹該類如何使用挣输。

3纬凤、 難點(diǎn)三:
怎樣實(shí)現(xiàn)頂層界面透明,在滑動(dòng)時(shí)顯示下層界面撩嚼,以及下層界面的聯(lián)動(dòng)停士。

分析:

  • fragment之間,移動(dòng)頂層fragment完丽,下層fragment設(shè)置setVisibility(VISIBLE)恋技,即可看到下層fragment,然后FragmentManager獲取下層framgent逻族,移動(dòng)其位置即可背景聯(lián)動(dòng)蜻底。 無版本兼容問題。
  • activity之間聘鳞,將頂層activity轉(zhuǎn)為透明薄辅,移動(dòng)activity的DecorView時(shí),即可看到下層的activity抠璃。將頂層activity轉(zhuǎn)為透明站楚,需要反射調(diào)用activity的convertToTranslucent方法。在Android 4.x部分手機(jī)上有問題搏嗡,5.0及其以后窿春,無問題拉一。

4、 難點(diǎn)四:
當(dāng)項(xiàng)目中已經(jīng)有一套自己定義的轉(zhuǎn)場(chǎng)動(dòng)畫旧乞,當(dāng)滑動(dòng)到一定的閾值銷毀頂層界面時(shí)蔚润,如何處理轉(zhuǎn)場(chǎng)動(dòng)畫。

分析:

  • activity的轉(zhuǎn)場(chǎng)動(dòng)畫良蛮,只需在startActivity抽碌、finish后使用overridePendingTransition()即可。

  • fragment的轉(zhuǎn)場(chǎng)動(dòng)畫决瞳,在setCustomAnimations方法中設(shè)置

      getSupportFragmentManager()
              .beginTransaction()
              .setCustomAnimations(R.anim.activity_or_fragment_enter, R.anim.activity_or_fragment_exit, R.anim.activity_or_fragment_pop_enter, R.anim.activity_or_fragment_pop_exit)
              .add(R.id.contentFrame, nextFragment, nextFragment.getClass().getSimpleName())
              .hide(currFragment)
              .addToBackStack(currFragment.getClass().getSimpleName())
              .commit();
    

在這里設(shè)置好了之后,fragment界面正常退出時(shí)左权,會(huì)調(diào)用設(shè)置的退出動(dòng)畫皮胡。但是當(dāng)手指從左到右滑動(dòng),松開時(shí)超過一定的閾值時(shí)赏迟,觸發(fā)頂層界面的銷毀屡贺,這時(shí)頂層界面需要無動(dòng)畫退出。
Fragment有個(gè)方法onCreateAnimation锌杀,當(dāng)轉(zhuǎn)場(chǎng)動(dòng)畫發(fā)生前甩栈,會(huì)回調(diào)此方法。我們重寫此方法糕再,在觸發(fā)頂層界面的銷毀前量没,鎖住動(dòng)畫即isLocking()返回true,該方法onCreateAnimation返回?zé)o動(dòng)畫突想。

@Override
public Animation onCreateAnimation(int transit, boolean enter, int nextAnim) {
    if (isLocking()) {
        return mNoAnim;
    }
    return super.onCreateAnimation(transit, enter, nextAnim);
}

5殴蹄、 難點(diǎn)五:
如何以最小的侵入性嵌入已有的項(xiàng)目,而不改變?cè)械睦^承關(guān)系猾担,而不大改動(dòng)原有代碼袭灯。

分析:為fagment、activity定義相應(yīng)的接口绑嘹,在提供一個(gè)實(shí)現(xiàn)類稽荧,面向接口編寫,嵌入你的項(xiàng)目時(shí)工腋,讓你項(xiàng)目的基類實(shí)現(xiàn)姨丈。即可少改動(dòng)你的項(xiàng)目代碼,不用改動(dòng)庫的代碼夷蚊。

6构挤、 難點(diǎn)六:
滑動(dòng)返回的Android版本兼容性。

分析:版本兼容問題在難點(diǎn)三中已經(jīng)體現(xiàn)惕鼓。如果你的項(xiàng)目使用“單activity多fragment”架構(gòu)筋现,無版本兼容問題。若使用“多activity多fragment”架構(gòu),4.x系統(tǒng)部分手機(jī)有問題矾飞,5.0及其以后無問題一膨。

致謝

滑動(dòng)返回庫:
https://github.com/ikew0ng/SwipeBackLayout
https://github.com/YoKeyword/SwipeBackFragment.git
https://github.com/tyzlmjj/SwipeBack

Android ViewDragHelper源碼解析
http://www.cnblogs.com/lqstayreal/p/4500219.html

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市洒沦,隨后出現(xiàn)的幾起案子豹绪,更是在濱河造成了極大的恐慌,老刑警劉巖申眼,帶你破解...
    沈念sama閱讀 222,000評(píng)論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件瞒津,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡括尸,警方通過查閱死者的電腦和手機(jī)巷蚪,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,745評(píng)論 3 399
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來濒翻,“玉大人屁柏,你說我怎么就攤上這事∮兴停” “怎么了淌喻?”我有些...
    開封第一講書人閱讀 168,561評(píng)論 0 360
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)雀摘。 經(jīng)常有香客問我裸删,道長(zhǎng),這世上最難降的妖魔是什么届宠? 我笑而不...
    開封第一講書人閱讀 59,782評(píng)論 1 298
  • 正文 為了忘掉前任烁落,我火速辦了婚禮,結(jié)果婚禮上豌注,老公的妹妹穿的比我還像新娘伤塌。我一直安慰自己,他們只是感情好轧铁,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,798評(píng)論 6 397
  • 文/花漫 我一把揭開白布每聪。 她就那樣靜靜地躺著,像睡著了一般齿风。 火紅的嫁衣襯著肌膚如雪药薯。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 52,394評(píng)論 1 310
  • 那天救斑,我揣著相機(jī)與錄音童本,去河邊找鬼。 笑死脸候,一個(gè)胖子當(dāng)著我的面吹牛穷娱,可吹牛的內(nèi)容都是我干的绑蔫。 我是一名探鬼主播,決...
    沈念sama閱讀 40,952評(píng)論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼泵额,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼配深!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起嫁盲,我...
    開封第一講書人閱讀 39,852評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤篓叶,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后羞秤,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體缸托,經(jīng)...
    沈念sama閱讀 46,409評(píng)論 1 318
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,483評(píng)論 3 341
  • 正文 我和宋清朗相戀三年瘾蛋,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了嗦董。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,615評(píng)論 1 352
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡瘦黑,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出奇唤,到底是詐尸還是另有隱情幸斥,我是刑警寧澤,帶...
    沈念sama閱讀 36,303評(píng)論 5 350
  • 正文 年R本政府宣布咬扇,位于F島的核電站甲葬,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏懈贺。R本人自食惡果不足惜经窖,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,979評(píng)論 3 334
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望梭灿。 院中可真熱鬧画侣,春花似錦、人聲如沸堡妒。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,470評(píng)論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽皮迟。三九已至搬泥,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間伏尼,已是汗流浹背忿檩。 一陣腳步聲響...
    開封第一講書人閱讀 33,571評(píng)論 1 272
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留爆阶,地道東北人燥透。 一個(gè)月前我還...
    沈念sama閱讀 49,041評(píng)論 3 377
  • 正文 我出身青樓沙咏,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國和親兽掰。 傳聞我的和親對(duì)象是個(gè)殘疾皇子芭碍,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,630評(píng)論 2 359

推薦閱讀更多精彩內(nèi)容

  • Android 自定義View的各種姿勢(shì)1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 172,302評(píng)論 25 707
  • 嵩山市場(chǎng)小籠包 趁著夜色剛起,沿途的路燈亮起白熾的燈光孽尽。騎上沒有后座的山地車窖壕,逐次從三三兩兩的人群旁掠過...
    走屬于自己的路吧閱讀 382評(píng)論 0 2
  • 文/娟子 很多時(shí)候熏挎,我更享受一個(gè)人獨(dú)處的生活速勇。所以當(dāng)我背起行囊,去到一個(gè)陌生的城市工作坎拐,即使沒有熟人烦磁,也沒有朋友,...
    娟子曰閱讀 1,902評(píng)論 12 14
  • 你用泥巴捏一座城 說將來要娶我進(jìn)門 轉(zhuǎn)多少身 過幾次門 虛擲青春 ...
    十七柒柒閱讀 254評(píng)論 0 0
  • 現(xiàn)代人的崩潰是一種默不作聲的崩潰。不會(huì)摔門砸東西积担,不會(huì)流眼淚或歇斯底里陨晶。但可能某一秒突然就積累到極致了,也不說話帝璧,...
    迪迪didi閱讀 346評(píng)論 0 0