Android Navigation組件(三)

在組件化項目中使用Navigation

Navigation組件目前并不能完美的支持組件化項目,主要問題是在module中聲明的graph中destination不能直接被App引用到切黔,在運(yùn)行時會找不到對應(yīng)的destination. 主要navigation資源的原因砸脊,目前設(shè)計中Navigation graph是獨(dú)立的具篇,graph中聲明的destination是無法共享的纬霞。

雖然Navigation graph中可以include其他的navigation graph, 但是include之后的graph還是無法共享聲明的destination。

官方近期更新了Navigation組件驱显,支持了Dynamic module诗芜,新增了一個<include-dynamic/>實(shí)現(xiàn)瞳抓,不支持deepLink. 由于國內(nèi)使用不了該功能,就不再描述了伏恐。

其他實(shí)現(xiàn)方式

  1. 只有一個navigation graph

將所有模塊中的fragment都聲明在App的一個Navigation graph內(nèi)孩哑,這樣是可行的,但是這種方式解耦違反組件化的邏輯翠桦,而且只有一個navigation graph横蜒,所有destination的改動都需要修改這個graph,維護(hù)成本高销凑。

  1. 通過include graph實(shí)現(xiàn)跳轉(zhuǎn)

App中的Nav graph include其他模塊的Nav graph丛晌,然后通過action跳轉(zhuǎn)到下個Nav graph, 如:

<action
      android:id="@+id/action_to_next_fragment"
      app:destination="@navigation/nav_graph2" />

調(diào)用這個action之后是可以跳轉(zhuǎn)到下個Nav graph中聲明的app:startDestination對應(yīng)的fragment. 如果下個nav_graph沒有聲明startDestination是不行的。

這個方案也有一個很大的缺陷斗幼,就是不能直接Navigation到include的graph中的非startDestination fragment. 只能在graph內(nèi)部進(jìn)行跳轉(zhuǎn)澎蛛。而且聲明的全局action都跳轉(zhuǎn)不過去。

  1. deepLink
    使用deepLink可以解決這個問題蜕窿,跟方案2前面的步驟一樣谋逻。然后需要在模塊中對外暴露的fragment加
    <deepLink />, 這樣就可以直接navigate過去。 這個方案目前是最可行的方案桐经,但是感覺deepLink被濫用毁兆,因?yàn)閐eepLink的真正作用是通過外部跳轉(zhuǎn)進(jìn)入。對于比較復(fù)雜的項目阴挣,可能好多fragment都需要添加deepLink荧恍。而且deepLink的傳參數(shù)格式需要完全匹配,容易出錯屯吊。

  2. 自動合并Nav graph
    可以像官方處理AndroidManifest.xml一樣送巡,在編譯時將所有module中的nav_graph文件中聲明的destination都合并到app中的nav_graph文件中,理論上可以解決該問題盒卸。但是這個方案有也有很多要考慮的問題

存在的問題:

  • AndroidManifest是自動生成的文件骗爆,不是用戶創(chuàng)建的,而且在其他用戶生成的layout文件中有依賴蔽介,如果在編譯前直接修改的話就不太優(yōu)雅摘投。
  • 合并只能合并到app的nav graph,每次編譯都需要檢查是否合并虹蓄,合并之后的文件處理不太優(yōu)雅犀呼。

若是直接合并到app的nav graph中,則需要一個備份文件薇组,在編譯完成之后是需要還原回去的外臂,這個操作本身就不太合理。正常的操作將所有nav graph文件生成為一個新的xml文件律胀,生成到build/generated/文件下宋光,然后修改布局中app:navGraph中的對應(yīng)的依賴貌矿,由于這些布局文件不是生成的,都是開發(fā)者自己創(chuàng)建的罪佳,所以不太優(yōu)雅逛漫。而且需要尋找聲明app:navGraph的地方,編譯前修改赘艳,編譯完成之后需要還原酌毡。

還有一種方案就是修改編譯之后的resouce.arsc文件,這個操作比較復(fù)雜蕾管,需要解ResourceTable阔馋,找到對應(yīng)的資源文件,修改生成新的resouce.arsc替換就行了娇掏。這個方案比較復(fù)雜呕寝,而且兼容性問題比較多,需要考慮Android系統(tǒng)和gradle婴梧,Android編譯API的兼容性問題下梢,開發(fā)和維護(hù)成本都比較高。

這個方案應(yīng)該是最合理的方案塞蹭,官方后面可能會解決這個問題孽江。

Navigation組件與Router

在組件化項目中一般都會使用Router來導(dǎo)航,由于之前的Router方案都是針對Activity的番电,之前的fragment添加岗屏,替換,移除等操作嚴(yán)重依賴Activity, 所以使用Router直接跳轉(zhuǎn)到對應(yīng)的fragment是比較麻煩的漱办。使用navigation組件之后就可以比較簡單的實(shí)現(xiàn)了这刷。

以前Router綁定的是URI和activity的class, 一般都是通過注解自動綁定。現(xiàn)在需要定URI, fragment或action或deepLink. 如果deepLink格式統(tǒng)一都不需要綁定娩井,直接使用即可暇屋。注解需要做調(diào)整。
例如:綁定URI和Fragment, 之前的綁定的注解是這樣的:

@Route(path = "/test/list")
class TestActivity : Activity {
      ...
}

因?yàn)閚avigation跳轉(zhuǎn)到Fragment并不需要Fragment的class洞辣,需要的是在nav graph聲明的id. 所以需要注解添加參數(shù)來綁定咐刨,可以改為:

@Route(path = "/test/list", resId = R.id.testfragment)
class TestFragment : Fragment {
      ...
}

或者是deepLink, 如果path與deepLink的URI一直都不用綁定

@Route(path = "/test/list", deepLink = "app://test/list")
class TestFragment : Fragment {
      ...
}

action不太一樣,action針對的是動作扬霜,所以不應(yīng)該將包含action的注解聲明在Fragment上.可以聲明在方法上定鸟,如:

object NaviControllerHelper{

    @RouteAction(path = "/test/list")
    fun navigateToDetail(navController: NavController){
        navController.navigate(R.id.action_to_detail)
    }

}

然后通過注解獲取到方法名稱,反射調(diào)用這個方法即可著瓶。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末联予,一起剝皮案震驚了整個濱河市谴供,隨后出現(xiàn)的幾起案子叶骨,更是在濱河造成了極大的恐慌显歧,老刑警劉巖栅组,帶你破解...
    沈念sama閱讀 216,591評論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件首繁,死亡現(xiàn)場離奇詭異棉磨,居然都是意外死亡子檀,警方通過查閱死者的電腦和手機(jī)浴韭,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,448評論 3 392
  • 文/潘曉璐 我一進(jìn)店門客叉,熙熙樓的掌柜王于貴愁眉苦臉地迎上來诵竭,“玉大人,你說我怎么就攤上這事兼搏÷盐浚” “怎么了?”我有些...
    開封第一講書人閱讀 162,823評論 0 353
  • 文/不壞的土叔 我叫張陵佛呻,是天一觀的道長裳朋。 經(jīng)常有香客問我,道長吓著,這世上最難降的妖魔是什么鲤嫡? 我笑而不...
    開封第一講書人閱讀 58,204評論 1 292
  • 正文 為了忘掉前任,我火速辦了婚禮绑莺,結(jié)果婚禮上暖眼,老公的妹妹穿的比我還像新娘。我一直安慰自己纺裁,他們只是感情好诫肠,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,228評論 6 388
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著欺缘,像睡著了一般栋豫。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上谚殊,一...
    開封第一講書人閱讀 51,190評論 1 299
  • 那天笼才,我揣著相機(jī)與錄音,去河邊找鬼络凿。 笑死骡送,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的絮记。 我是一名探鬼主播摔踱,決...
    沈念sama閱讀 40,078評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼怨愤!你這毒婦竟也來了派敷?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 38,923評論 0 274
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎篮愉,沒想到半個月后腐芍,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,334評論 1 310
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡试躏,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,550評論 2 333
  • 正文 我和宋清朗相戀三年猪勇,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片颠蕴。...
    茶點(diǎn)故事閱讀 39,727評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡泣刹,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出犀被,到底是詐尸還是另有隱情椅您,我是刑警寧澤,帶...
    沈念sama閱讀 35,428評論 5 343
  • 正文 年R本政府宣布寡键,位于F島的核電站掀泳,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏西轩。R本人自食惡果不足惜开伏,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,022評論 3 326
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望遭商。 院中可真熱鬧固灵,春花似錦、人聲如沸劫流。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,672評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽祠汇。三九已至仍秤,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間可很,已是汗流浹背诗力。 一陣腳步聲響...
    開封第一講書人閱讀 32,826評論 1 269
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留我抠,地道東北人苇本。 一個月前我還...
    沈念sama閱讀 47,734評論 2 368
  • 正文 我出身青樓,卻偏偏與公主長得像菜拓,于是被迫代替她去往敵國和親瓣窄。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,619評論 2 354