web-dev-qa-db-fra.com

Comment fermer la navigation DrawerLayout onBackPressed dans le fragment des contrôles de navigation

J'ai créé un projet Androidx avec le modèle Navigation. Maintenant, je veux fermer tiroirLayout onBackPressed() en fragment. Et aussi, je veux définir OnClickListener pour les éléments de menu de tiroir dans mon menu personnalisé, il n'y a aucun moyen, je suppose, de remplacer la onBackPressed() en fragment.

Je veux savoir comment je peux y arriver?

Voici mon tiroir:

<androidx.drawerlayout.widget.DrawerLayout
    xmlns:Android="http://schemas.Android.com/apk/res/Android"
    xmlns:tools="http://schemas.Android.com/tools"
    xmlns:app="http://schemas.Android.com/apk/res-auto"
    Android:orientation="vertical"
    Android:id="@+id/drawerLayoutHome"
    Android:layout_width="match_parent"
    Android:layout_height="match_parent">

    <com.google.Android.material.navigation.NavigationView
        Android:id="@+id/nav_view"
        Android:layout_width="350dp"
        Android:layout_height="match_parent"
        Android:layout_gravity="start"
        Android:background="@color/colorPrimaryDark"
        Android:fitsSystemWindows="true"
        app:headerLayout="@layout/nav_header_main"
        app:itemIconTint="@color/white"
        app:itemTextColor="@color/white"
        app:menu="@menu/activity_main_drawer"/>

</androidx.drawerlayout.widget.DrawerLayout>

Je veux y parvenir:

override fun onBackPressed() {

    if (drawerLayoutHome.isDrawerOpen(GravityCompat.END)) {
        drawerLayoutHome.closeDrawer(GravityCompat.END)
    } else {
        super.onBackPressed()
    }
}

Mais c'est pour Activity, comment y parvenir dans Fragment?

17
Arbaz Pirwani

Bonjour, vous pouvez le faire en mettant votre fragment en activité et en remplaçant onbackpress avec du code kotlin

C'est votre fonction de contre-pression et vous pouvez obtenir votre hôte de navigation et ensuite vérifier votre fragment actuel ou le fragment dans lequel vous souhaitez ouvrir le tiroir.

override fun onBackPressed() {

    val navHostFragment = supportFragmentManager.findFragmentById(R.id.fragmentHomeHost)
    val completeFragmentList = navHostFragment?.childFragmentManager?.fragments

    if (completeFragmentList != null) {
        when {
            completeFragmentList[0] is HomeFragment -> {
                val home = (completeFragmentList[0] as HomeFragment)


            }
            else -> super.onBackPressed()
        }
    }

    if (drawerLayoutHome.isDrawerOpen(GravityCompat.START)) {
        drawerLayoutHome.closeDrawer(GravityCompat.START)
    } else {
        super.onBackPressed()
    }
}

Et voici houe, vous pouvez obtenir l'écouteur d'élément de sélection

override fun onNavigationItemSelected(item: MenuItem): Boolean {
    drawerLayoutHome.closeDrawer(GravityCompat.START)

    return true
}
8
Hello world

Vous pouvez le faire dans un Fragment en implémentant OnBackStackChangedListener sur votre activité de tiroir.
Ensuite, liez votre tiroir avec ActionBarDrawerToggle et remplacez onBackStackChanged() et synchronisez votre bascule de tiroir.

Voici l'extrait complet:

public class MainActivity extends AppCompatActivity implements FragmentManager.OnBackStackChangedListener {


    private DrawerLayout drawer;
    private ActionBarDrawerToggle toggle;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        //Bind listener here
        getSupportFragmentManager().addOnBackStackChangedListener(this);
        drawer = findViewById(R.id.drawer_layout);
        toggle = new ActionBarDrawerToggle(this, drawer, toolbar, R.string.navigation_drawer_open, R.string.navigation_drawer_close);
        toggle.setToolbarNavigationClickListener(view -> onBackPressed());
        drawer.addDrawerListener(toggle);
        toggle.syncState();

    }


    //Override fragment backstack lister method 
    @Override
    public void onBackStackChanged() {
        //toggle.setDrawerIndicatorEnabled(getSupportFragmentManager().getBackStackEntryCount() == 0);
        //getSupportActionBar().setDisplayHomeAsUpEnabled(getSupportFragmentManager().getBackStackEntryCount() > 0);
        toggle.syncState();
    }

    @Override
    public void onBackPressed() {
        drawer = findViewById(R.id.drawer_layout);
        if (drawer.isDrawerOpen(GravityCompat.START))
            drawer.closeDrawer(GravityCompat.START);
        else {
            //super.onBackPressed();
        }
    }
}

J'espère que cela t'aidera.

4
Mehul Solanki

Réponse courte

Il n'est pas possible d'intercepter onBackPressed le rappel à l'intérieur de Fragment sans ajouter de code supplémentaire à l'intérieur de l'hébergement Activity. Il n'est tout simplement pas implémenté dans Android SDK. Arrête.

Réponse originale

Il n'y a pas de rappel onBackPressed dans la classe Fragment. Mais vous pouvez l'implémenter vous-même:

Créez une interface:

interface FragmentOnBackPressedListener {
  fun onBackPressed()
}

Maintenant dans votre activité:

override fun onBackPressed() {
  // find top fragment
  val currentFragment = supportFragmentManager
    .findFragmentById(R.id.your_nav_Host_fragment_id)?.let {
      it.childFragmentManager.fragments.getOrNull(0)
    }
  // check if it implements FragmentOnBackPressedListener 
  if (currentFragment is FragmentOnBackPressedListener ) {
    // if it does, transfer flow to the fragment
    return currentFragment.onBackPressed()
  }
  // if it doesn't, apply default behaviour
  super.onBackPressed()
}

Puis dans votre fragment:

class ExampleFragment : Fragment(), FragmentOnBackPressedListener {

  override fun onBackPressed() {
    // close your drawer layout here if visible

    // Also: to close fragment, invoke 
    // findNavController().navigateUp() or findNavController().popBackStack()
  }

}
2
xinaiz

J'ai eu un problème similaire.

J'ai donc ajouté ceci dans onBackPressed de mon fichier d'activité.

FragmentManager manager = getSupportFragmentManager();
 if (manager.getBackStackEntryCount() > 0) {
                while (manager.getBackStackEntryCount() > 0) {
                    manager.popBackStackImmediate();
                }
0
sanjeev