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
?
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
}
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.
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.
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()
}
}
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();
}