web-dev-qa-db-ja.com

Androidナビゲーションアーキテクチャコンポーネント-現在表示されているフラグメントを取得

ナビゲーションコンポーネントを試す前に、フラグメントトランザクションを手動で実行し、現在のフラグメントを取得するためにフラグメントタグを使用していました。

val fragment:MyFragment = supportFragmentManager.findFragmentByTag(tag):MyFragment

私のメインアクティビティレイアウトには次のようなものがあります。

<fragment
        Android:layout_width="match_parent"
        Android:layout_height="match_parent"
        Android:id="@+id/nav_Host"
        app:navGraph= "@navigation/nav_item"
        Android:name="androidx.navigation.fragment.NavHostFragment"
        app:defaultNavHost= "true"
        />

ナビゲーションコンポーネントによって現在表示されているフラグメントを取得するにはどうすればよいですか?やること

supportFragmentManager.findFragmentById(R.id.nav_Host)

NavHostFragmentを返し、表示された 'MyFragment`を取得したい。

ありがとうございました。

36
Alin

私は今のところ方法を発見することができました。それは次のとおりです。

NavHostFragment navHostFragment = supportFragmentManager.findFragmentById(R.id.nav_Host);
navHostFragment.getChildFragmentManager().getFragments().get(0);

もちろん、それが最初のフラグメントであることを知っています。私はまだこれなしの方法を調査しています。私はそれが最善の方法ではないことに同意しますが、それは今のところ何かであるべきです。

38
Andrei Toader

現在のフラグメントインスタンスを取得する方法はありません。ただし、以下のコードを使用して、最後に追加されたフラグメントのIDを取得できます。

navController.getCurrentDestination().getId()

ナビゲーションファイルでIDを返します。お役に立てれば。

20
slhddn

NavフラグメントのchildFragmentManager primaryNavigationFragmentプロパティを確認する必要があります。これは、現在表示されているフラグメントが参照される場所です。

val navHost = supportFragmentManager.findFragmentById(R.id.main_nav_fragment)
    navHost?.let { navFragment ->
        navFragment.childFragmentManager.primaryNavigationFragment?.let {fragment->
                //DO YOUR STUFF
        }
    }
}
14
Nicolas Pietri

addOnDestinationChangedListenerを持つアクティビティでNavHostFragmentを使用します

 NavController navController= Navigation.findNavController(MainActivity.this,R.id.your_nav_Host);

        navController.addOnDestinationChangedListener(new NavController.OnDestinationChangedListener() {
            @Override
            public void onDestinationChanged(@NonNull NavController controller, @NonNull NavDestination destination, @Nullable Bundle arguments) {
                Log.e(TAG, "onDestinationChanged: "+destination.getLabel());
            }
        });
3
Mukul Bhardwaj

これは遅いかもしれませんが、まだ探している人のために

val currentfraagment=NavHostFragment.findNavController(nav_Host_fragment).currentDestination!!.id

その後、次のようなことができます

if(currentfraagment == R.id.myFragemnt){
     //do something
}

これはkotlin用であり、Javaコードはほぼ同じであることに注意してください

3
MoTahir

実用的なソリューションが見つかりました。

private fun getCurrentFragment(): Fragment? {
    val currentNavHost = supportFragmentManager.findFragmentById(R.id.nav_Host_id)
    val currentFragmentClassName = ((this as NavHost).navController.currentDestination as FragmentNavigator.Destination).className
    return currentNavHost?.childFragmentManager?.fragments?.filterNotNull()?.find {
        it.javaClass.name == currentFragmentClassName
    }
}
2
Tomas Kuhn

これは最もクリーンなソリューションのようです。

1。次の拡張子を作成します

import androidx.fragment.app.Fragment
import androidx.fragment.app.FragmentManager

fun FragmentManager.getCurrentNavigationFragment(): Fragment? =
    primaryNavigationFragment?.childFragmentManager?.fragments?.first()

2。ActivityではNavHostFragmentと一緒に使用します:

val currentFragment = supportFragmentManager.getCurrentNavigationFragment()
1
Aleksandar Ilic

getChildFragmentManager()で確認してください

NavHostFragment fragment = supportFragmentManager.findFragmentById(R.id.nav_Host);
MyFragment frag = (MyFragment) fragment.getChildFragmentManager().findFragmentByTag(tag);
1

まず、IDで現在のフラグメントを取得し、次にそのIDに応じてフラグメントを見つけることができます。

int id = navController.getCurrentDestination().getId();
Fragment fragment = getSupportFragmentManager().findFragmentById(id)l
0
Abu-Bakr

作る:

•フラグメント内のボタン:

val navController = findNavController(this)
  navController.popBackStack()

•アクティビティonBackPressed()

override fun onBackPressed() {
        val navController = findNavController(R.id.nav_Host_fragment)
        val id = navController.currentDestination?.getId()
        if (id == R.id.detailMovieFragment){
            navController.popBackStack()
            return
        }

        super.onBackPressed()
    } 

アクティビティでフラグメントオブジェクトを定義します。そして、各フラグメントから、フラグメントオブジェクトを渡すことでこのメソッドを呼び出します。そのため、静的フラグメントオブジェクトは毎回現在表示中のフラグメントによってオーバーライドされます。

//method in MainActivity
private static Fragment fragment;

public void setFragment(Fragment fragment){
this.fragment = fragment;
}

//And from your fragment class, you can call
((<yourActivity in which fragment present>)getActivity()).setFragment(<your fragment object>);

//if you want to set it directly;
 ((<yourActivity in which fragment present>)getActivity()).fragment=<your fragment object>;

より良いアプローチのために、フラグメントからアクティビティにコールバックを設定して、現在のフラグメントオブジェクトを渡すこともできます。

0
Ranjan

Andrei Toaders answerMukul Bhardwajs answerOnBackStackChangedListenerと組み合わせました。

属性として:

private FooFragment fragment;

私のonCreate

NavHostFragment navHostFragment = (NavHostFragment) getSupportFragmentManager().findFragmentById(R.id.nav_Host);
FragmentManager navHostManager = Objects.requireNonNull(navHostFragment).getChildFragmentManager();
FragmentManager.OnBackStackChangedListener listener = () -> {
        List<Fragment> frags = navHostManager.getFragments();
        if(!frags.isEmpty()) {
            fragment = (FooFragment) frags.get(0);
        }
};
navController.addOnDestinationChangedListener((controller, destination, arguments) -> {
        if(destination.getId()==R.id.FooFragment){
            navHostManager.addOnBackStackChangedListener(listener);
        } else {
            navHostManager.removeOnBackStackChangedListener(listener);
           fragment = null;
        }
});

このようにして、後で表示されるフラグメントを取得できます。 fragsをループして、instanceofで複数のフラグメントをチェックすることもできます。

0
Siggy1000

これを達成する最良の方法は、フラグメントライフサイクルコールバックを登録することです。

元の質問によると、NavHostFragmentが次のように定義されている場合...

<fragment
        Android:layout_width="match_parent"
        Android:layout_height="match_parent"
        Android:id="@+id/nav_Host"
        app:navGraph= "@navigation/nav_item"
        Android:name="androidx.navigation.fragment.NavHostFragment"
        app:defaultNavHost= "true"
        />

次に、メインアクティビティonCreate(..)...

nav_Host.childFragmentManager.registerFragmentLifecycleCallbacks(
    object:FragmentManager.FragmentLifecycleCallbacks() {
        override fun onFragmentViewCreated(
            fm: FragmentManager, f: Fragment, v: View,
            savedInstanceState: Bundle?
        ) {
            // callback method always called whenever a
            // fragment is added, or, a back-press returns
            // to the start-destination
        }
    }
)

他のコールバックメソッドは、要件に合わせてオーバーライドできます。

0
miguelt

下部のナビゲーションビューをセットアップするためにこれを行う必要がありますが、次のようにしました。

val navController = Navigation.findNavController(requireActivity(), R.id.nav_tabs_home)
        val bottomNavBar: BottomNavigationView = nav_content_view
        NavigationUI.setupWithNavController(bottomNavBar, navController)
0
Roque Rueda