web-dev-qa-db-ja.com

Android ViewPagerおよびTabLayoutを使用したJetpackナビゲーション

新しいアプリでは、Jetpack Navigation Libraryを使用して適切なバックナビゲーションを実装します。ナビゲーションの最初のレベルは、ドキュメントに記載されているジェットパックナビゲーションで正常に動作するナビゲーションドロワーです。ただし、ViewPagerおよびTabLayoutで実装された別のレベルのナビゲーションがあります。 TabLayoutによって切り替えられたフラグメントには、追加の線形ナビゲーション階層が含まれます。ただし、Jetpack NavigationのViewPager/TabLayoutはサポートされていないようです。 FragmentPagerAdapterを実装する必要があり、タブを切り替えるとマネージバックスタックが終了します。トップレベルのナビゲーションと各タブ内のナビゲーションとの間には接続がありません。 Jetpack Navigationでこれを機能させる方法はありますか?

19
ngu

Jetpack NavigationTabLayoutを処理するさまざまなアプローチを試しました。ただし、タブを複数回切り替える完全な履歴があるなどの問題が発生します。

既知のGoogleの閲覧Androidデモのリクエストを出す前の問題、私はこれを見つけました 既存の問題

そのステータスは、Closedとしてマークされ、Intended Behaviorと次の説明があります:

ナビゲーションはバックスタックに影響する要素に焦点を当てており、タブはバックスタックに影響を与えません-引き続きViewPagerTabLayoutを使用してタブを管理する必要があります- Youtube training =。

7
sunadorer

これまでのところ私のために働いたもの:

Navigation_graph.xml内

  • viewPagerFragmentをネストされたグラフのルートにする
  • 入れ子になったグラフに入出力ナビゲーションを接続します

ネストされたグラフ内:

  • viewPagerのChildFragmentsをネストされたグラフに追加します

ViewPagerを変更する必要はありませんでした。子フラグメント用にルートが作成されたため、そこからナビゲーションが可能になりました。

1
user2965003

はい、ただし、クラス Navigator を実装してオーバーライドすることにより、独自のカスタム宛先を実装する必要があります少なくともメソッド popBackStack() および navigate()

navigateで、ViewPager.setCurrentTab()を呼び出してバックスタックに追加する必要があります。何かのようなもの:

_lateinit var viewPager: ViewPager? = null // you have to provide this in the constructor

private val backstack: Deque<Pair<Int, View>> = ArrayDeque

override fun navigate(destination: Destination, args: Bundle?,
                      navOptions: NavOptions?, navigatorExtras: Extras?
): NavDestination? {

    viewPager.currentItem = destination.id
    backstack.remove(destination.id) // remove so the stack has never two of the same
    backstack.addLast(destination.id)

    return destination
}
_

popBackStackで、最後に選択したアイテムを元に戻す必要があります。何かのようなもの:

_override fun popBackStack(): Boolean {
    if(backstack.size() <= 1) return false

    viewPager.currentItem = backstack.peekLast()
    backstack.removeLast()

    return true
}
_

FragmentDialogのカスタムナビゲーターの Androidドキュメント および この例 の簡単な説明を見つけることができます。

ViewPagerNavigatorを実装したら、それをNavControllerに追加し、NavController.navigate()を呼び出すタブビュー選択のリスナーを設定する必要があります。

誰かがこの一般的なパターン(ViewPager、ViewGroup、FragmentDialog)のライブラリを実装し、誰かがそれを見つけたらコメントに追加してくれることを願っています。

0
Allan Veloso