Wie kann ich das aktuelle Fragment in NavHostFragment abrufen?

Lesezeit: 4 Minuten

Benutzer-Avatar
Benjamin Bihr

Ich habe versucht, eine Methode in den neuen Navigationskomponenten zu finden, aber ich habe nichts darüber gefunden.

Ich habe das aktuelle Ziel mit:

mainHostFragment.findNavController().currentDestination

Aber ich kann keinen Verweis auf das angezeigte Fragment erhalten.

  • Ich fürchte, Sie müssen es manuell handhaben

    – guisantogui

    4. Juni 2018 um 21:49 Uhr

  • Was versuchst du zu machen?

    – ianhanniballake

    4. Juni 2018 um 22:04 Uhr

  • @ianhanniballake Meine Host-Aktivität benötigt Referenzen, um mit ihren Fragmenten zu kommunizieren

    – Benjamin Bihr

    4. Juni 2018 um 22:10 Uhr

Benutzer-Avatar
ist abwesend

Verweis auf das angezeigte Fragment (AndroidX):

Java

public Fragment getForegroundFragment(){
    Fragment navHostFragment = getSupportFragmentManager().findFragmentById(R.id.nav_host_fragment);
    return navHostFragment == null ? null : navHostFragment.getChildFragmentManager().getFragments().get(0);
}

kotlin

val navHostFragment: Fragment? =
        supportFragmentManager.findFragmentById(R.id.nav_host_fragment)
navHostFragment?.childFragmentManager?.fragments?.get(0)

Hier nav_host_fragment ist eine ID der fragment tag in deinem activity_main.xml mit android:name="androidx.navigation.fragment.NavHostFragment"

  • In meinem Fall gibt mir ?.childFragmentManager?.fragments?.last() das aktuelle Fragment

    – Milad Faridnia

    24. Mai um 13:55 Uhr

  • Wow, hackige Antworten. childFragmentManager.findFragmentById existiert.

    – John Glen

    9. Juni um 21:23 Uhr

Die Navigation stellt keinen Mechanismus bereit, um die Implementierung (dh das Fragment selbst) des aktuellen Ziels zu erhalten.

Gemäß der Erstellen von Ereignisrückrufen für die Aktivitätsollten Sie entweder mit Ihrem Fragment per kommunizieren

  • Wenn das Fragment einen Rückruf in seinem registriert onAttach -Methode, die Ihre Aktivität in eine Instanz einer von Ihnen bereitgestellten Schnittstelle umwandelt
  • Verwenden Sie eine gemeinsame ViewModel die Ihre Aktivität und Ihr Fragment zur Kommunikation verwenden.

  • Alle Links zeigen, wie man zwischen Fragmenten kommuniziert. Aber wie können wir die Fragmentmethode aus der Aktivität aufrufen, wenn die Navigation keinen Mechanismus bietet, um die Implementierung des aktuellen Ziels zu erhalten?

    – Sever

    17. April 2019 um 18:00 Uhr


  • @Sever – siehe dieses Problem und wie zu verwenden getPrimaryNavigationFragment() um das aktuelle Fragment abzurufen.

    – ianhanniballake

    17. April 2019 um 18:03 Uhr

  • Vielen Dank. Es klappt. val navHostFragment = supportFragmentManager.primaryNavigationFragment as NavHostFragment val yourFragment = currentFragmentClassName.childFragmentManager.primaryNavigationFragment as YourFragment

    – Sever

    17. April 2019 um 18:25 Uhr


  • @ianhanniballake: Entschuldigung, ich habe nicht verstanden, ob es eine Möglichkeit gibt, das Vordergrundfragment zu erhalten getPrimaryNavigationFragment() jetzt oder sie werden nur in Zukunft eine solche Gelegenheit bieten!?

    – ist abwesend

    11. Dezember 2019 um 6:17 Uhr

  • Nun, um ViewModel zwischen zwei Fragmenten zu teilen, muss eines von ihnen sein Besitzer sein. Und der andere muss diesen Eigentümer finden, um dieses ViewModel abzurufen. Also … benutze niemals die Navigation, sie ist verzögert.

    – Miha_x64

    18. April 2021 um 17:18 Uhr

Sie können so etwas tun:

  override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
        super.onActivityResult(requestCode, resultCode, data)

        val navHostFragment = supportFragmentManager.fragments.first() as? NavHostFragment
        if(navHostFragment != null) {
            val childFragments = navHostFragment.childFragmentManager.fragments
            childFragments.forEach { fragment ->
                fragment.onActivityResult(requestCode, resultCode, data)
            }
        }
    }

Aber für fortgeschrittenere Kommunikation Listener mit Callback-Methoden registriert in Fragment.onAttach() (Fragment -> Activity rather one direction communication) und SharedViewModel (bidirectionalwichtig zu haben ViewModelProviders, and Lifecycle owner that is scoped to getActivity() eher)

  • Sie können entfernen as? NavHostFragment und machen Sie die if-Anweisung if (navHostFragment is NavHostFragment)

    – Schalbert

    1. Dezember 2021 um 19:43 Uhr

Basierend auf anderen Antworten

Fragment navHostFragment = getSupportFragmentManager().getPrimaryNavigationFragment();
Fragment fragment = navHostFragment.getChildFragmentManager().getFragments().get(0);

((Your Fragment Class) fragment).(public method inside the fragment)

hat bei mir funktioniert

Mit Michals Antwort habe ich diese Erweiterungsfunktion zum Testen geschrieben:

@Suppress("UNCHECKED_CAST")
fun <F : Fragment> AppCompatActivity.getFragment(fragmentClass: Class<F>): F? {
    val navHostFragment = this.supportFragmentManager.fragments.first() as NavHostFragment

    navHostFragment.childFragmentManager.fragments.forEach {
        if (fragmentClass.isAssignableFrom(it.javaClass)) {
            return it as F
        }
    }

    return null
}

So verwendet:

val myFragment = activity.getFragment(MyFragment::class.java)

  • Sie können dies herunterquetschen inline fun <reified T : Fragment> FragmentManager.findFragmentByClass(): T? = fragments.firstOrNull { it is T } as T?

    – drdaanger

    8. November 2019 um 21:40 Uhr

Benutzer-Avatar
Elikill58

Sie können Folgendes tun:

@Override
public void onBackPressed() {
    super.onBackPressed();
   
    NavController navController = Navigation.findNavController(this, R.id.fragment);
    int id=navController.getCurrentDestination().getId();
    if(id == R.id.startGameFragment ){
        selectedPosition(0);
    } else if(id == R.id.gameFragment ){
        selectedPosition(1);
    } else if(id == R.id.endGameFragment){
        selectedPosition(2);
    }
}

private void selectedPosition(int pos){
    for (int i = 0; i >=nav_view.getMenu().size(); i++) {
        nav_view.getMenu().getItem(pos).setChecked(false);

    }
    nav_view.getMenu().getItem(pos).setChecked(true);
}

  • Sie können dies herunterquetschen inline fun <reified T : Fragment> FragmentManager.findFragmentByClass(): T? = fragments.firstOrNull { it is T } as T?

    – drdaanger

    8. November 2019 um 21:40 Uhr

Benutzer-Avatar
Zhar

Ich poste meine vollständige Antwort mit Androidx. Achtung: In meinem Fall musste ich eines der untergeordneten Fragmente abrufen (könnte nicht der erste sein).

Im Hauptaktivität Sie sollten etwas haben wie:

 @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Toolbar toolbar = findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);

        DrawerLayout drawer = findViewById(R.id.drawer_layout);
        NavigationView navigationView = findViewById(R.id.nav_view);
        // Passing each menu ID as a set of Ids because each
        // menu should be considered as top level destinations.
        mAppBarConfiguration = new AppBarConfiguration.Builder(
                 R.id.mytest, R.id.nav_help)
                .setDrawerLayout(drawer)
                .build();
        NavController navController = Navigation.findNavController(this, R.id.nav_host_fragment);
        NavigationUI.setupActionBarWithNavController(this, navController, mAppBarConfiguration);
        NavigationUI.setupWithNavController(navigationView, navController);
...

Dann müssen Sie eine Methode erstellen, um das gute Fragment abzurufen.

 private MyTestFragment getMyTestFragment(){
        MyTestFragment resultFragment = null;
        Fragment navHostFragment = getSupportFragmentManager().findFragmentById(R.id.nav_host_fragment);
        if(navHostFragment != null && navHostFragment.getChildFragmentManager() != null) {
            List<Fragment> fragmentList = navHostFragment.getChildFragmentManager().getFragments();
            for (Fragment fragment : fragmentList) {
                if (fragment instanceof MyTest) {
                    resultFragment = (MyTest) fragment;
                    break;
                }
            }
        }
        return resultFragment;
    }

Endlich verstehst du es.

1175740cookie-checkWie kann ich das aktuelle Fragment in NavHostFragment abrufen?

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy