Qu'est-ce que je fais?
J'ai essayé de travailler avec Androidx Navigation Drawer (<com.google.Android.material.navigation.NavigationView>
). J'ai lu la documentation ici , qui dit que pour gérer les sélections d'articles, nous pouvons utiliser setNavigationItemSelectedListener
.
Remarque: J'utilise également le composant de navigation de JetPack.
Ci-dessous: main_activity.xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.drawerlayout.widget.DrawerLayout xmlns:Android="http://schemas.Android.com/apk/res/Android"
xmlns:app="http://schemas.Android.com/apk/res-auto"
xmlns:tools="http://schemas.Android.com/tools"
Android:id="@+id/drawer_layout"
Android:layout_width="match_parent"
Android:layout_height="match_parent"
tools:context=".MainActivity">
<LinearLayout
Android:layout_width="match_parent"
Android:layout_height="match_parent"
Android:orientation="vertical">
<androidx.appcompat.widget.Toolbar
Android:id="@+id/toolbar"
Android:layout_width="match_parent"
Android:layout_height="?attr/actionBarSize"
Android:background="@color/colorPrimary"
Android:theme="@style/ThemeOverlay.AppCompat.Dark" />
<fragment
Android:id="@+id/nav_Host_fragment"
Android:name="androidx.navigation.fragment.NavHostFragment"
Android:layout_width="match_parent"
Android:layout_height="match_parent"
app:defaultNavHost="true"
app:navGraph="@navigation/nav_graph" />
</LinearLayout>
<com.google.Android.material.navigation.NavigationView
Android:id="@+id/navigationView"
Android:layout_width="wrap_content"
Android:layout_height="match_parent"
Android:layout_gravity="start"
Android:fitsSystemWindows="true"
app:menu="@menu/drawer_menu" />
</androidx.drawerlayout.widget.DrawerLayout>
Voici: MainActivity.Java
import Android.os.Bundle;
import Android.view.MenuItem;
import Android.widget.Toast;
import com.google.Android.material.navigation.NavigationView;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.widget.Toolbar;
import androidx.core.view.GravityCompat;
import androidx.drawerlayout.widget.DrawerLayout;
import androidx.navigation.NavController;
import androidx.navigation.Navigation;
import androidx.navigation.ui.NavigationUI;
public class MainActivity extends AppCompatActivity {
public Toolbar toolbar;
public DrawerLayout drawerLayout;
public NavController navController;
public NavigationView navigationView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
setupNavigation();
}
// Setting Up One Time Navigation
private void setupNavigation() {
toolbar = findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
drawerLayout = findViewById(R.id.drawer_layout);
navigationView = findViewById(R.id.navigationView);
navigationView.setNavigationItemSelectedListener(new NavigationView.OnNavigationItemSelectedListener() {
@Override
public boolean onNavigationItemSelected(@NonNull MenuItem menuItem) {
Toast.makeText(MainActivity.this, "Hello", Toast.LENGTH_SHORT).show();
return false;
}
});
navController = Navigation.findNavController(this, R.id.nav_Host_fragment);
NavigationUI.setupActionBarWithNavController(this, navController, drawerLayout);
NavigationUI.setupWithNavController(navigationView, navController);
}
@Override
public boolean onSupportNavigateUp() {
return NavigationUI.navigateUp(drawerLayout, Navigation.findNavController(this, R.id.nav_Host_fragment));
}
@Override
public void onBackPressed() {
if (drawerLayout.isDrawerOpen(GravityCompat.START)) {
drawerLayout.closeDrawer(GravityCompat.START);
} else {
super.onBackPressed();
}
}
}
Situation:
Tout s'affiche correctement, j'obtiens le Drawer
au moment de l'exécution, j'obtiens également le Hamburger
, cela fonctionne très bien pour afficher le NavigationView
avec les éléments de menu.
Ci-dessous: tiroir_menu.xml
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:Android="http://schemas.Android.com/apk/res/Android">
<group Android:checkableBehavior="single">
<item
Android:id="@+id/first"
Android:icon="@mipmap/ic_launcher"
Android:title="First" />
<item
Android:id="@+id/second"
Android:icon="@mipmap/ic_launcher"
Android:title="Second" />
<item
Android:id="@+id/third"
Android:icon="@mipmap/ic_launcher"
Android:title="Third" />
</group>
</menu>
Problème:
En tapant sur les éléments du menu, il ne répond pas à mes événements de clic, alias onNavigationItemSelected
. Comme vous pouvez voir mon MainActivity.Java
, le Toast
n'apparaît pas et aucun des ID de menu ne fonctionne à l'intérieur du commutateur.
J'ai essayé de nombreux exemples et différentes façons d'y parvenir.
Existe-t-il un moyen de faire en sorte que les éléments du menu répondent à mes événements sélectionnés?
Si vous avez besoin de plus de détails à ce sujet, veuillez commenter ci-dessous.
Merci beaucoup pour l'aide.
Je l'ai compris les gars.
Au cas où quelqu'un en aurait besoin, je le poste ici.
Au lieu de cela:
navigationView = findViewById(R.id.navigationView);
navigationView.setNavigationItemSelectedListener(new NavigationView.OnNavigationItemSelectedListener() {
@Override
public boolean onNavigationItemSelected(@NonNull MenuItem menuItem) {
Toast.makeText(MainActivity.this, "Hello", Toast.LENGTH_SHORT).show();
return false;
}
});
navController = Navigation.findNavController(this, R.id.nav_Host_fragment);
NavigationUI.setupActionBarWithNavController(this, navController, drawerLayout);
NavigationUI.setupWithNavController(navigationView, navController);
J'ai changé pour:
navigationView = findViewById(R.id.navigationView);
navController = Navigation.findNavController(this, R.id.nav_Host_fragment);
NavigationUI.setupActionBarWithNavController(this, navController, drawerLayout);
NavigationUI.setupWithNavController(navigationView, navController);
navigationView.setNavigationItemSelectedListener(new NavigationView.OnNavigationItemSelectedListener() {
@Override
public boolean onNavigationItemSelected(@NonNull MenuItem menuItem) {
Toast.makeText(MainActivity.this, "Hello", Toast.LENGTH_SHORT).show();
return false;
}
});
Et cela a fonctionné, peut-être que nous devons tout configurer avant d'attacher le onNavigationSelector
.
Vous n'avez peut-être pas compris tous les effets secondaires du changement de commande.
NavigationUI.setupWithNavController(navigationView, navController); // Line 1
navigationView.setNavigationItemSelectedListener({...}) // Line 2
NavigationUI
attache en interne NavigationView.OnNavigationItemSelectedListener
au NavigationView
à Line1
. Vous remplacez cet écouteur par votre écouteur personnalisé dans Line 2
.
Cela signifie que navController
ne fonctionnera pas et vous devez gérer toutes les actions de navigation manuellement dans votre écouteur personnalisé. Ainsi, la solution complète pourrait être quelque chose comme:
NavigationUI.setupWithNavController(navigationView, navController);
navigationView.setNavigationItemSelectedListener(
new NavigationView.OnNavigationItemSelectedListener() {
@Override
public boolean onNavigationItemSelected(@NonNull MenuItem menuItem) {
// TODO: do stuff
Toast.makeText(MainActivity.this, "Hello", Toast.LENGTH_SHORT).show();
// You need this line to handle the navigation
boolean handled = NavigationUI.onNavDestinationSelected(menuItem, navController);
if (handled) {
ViewParent parent = navigationView.getParent();
if (parent instanceof DrawerLayout) {
((DrawerLayout) parent).closeDrawer(navigationView);
}
}
return handled;
}
});
Remarque: vous souhaiterez peut-être toujours appeler setupWithNavController
avant de joindre votre écouteur personnalisé, car il fait autre chose que d'attacher l'écouteur de clic d'élément de navigation.
Dans le cas où quelqu'un qui cherche encore répondra comment avoir les deux: NavigationController pour gérer les éléments NavigationView, mais aussi pour avoir une action spécifique à l'intérieur de NavigationView.
Dans les éléments du menu de configuration du fichier menu.xml, comme d'habitude:
<menu>
<item
Android:id="@+id/fragment_settings"
Android:icon="@drawable/ic_settings"
Android:orderInCategory="3"
Android:title="@string/settings" />
<item
Android:id="@+id/share_app"
Android:icon="@drawable/ic_share"
Android:orderInCategory="4"
Android:onClick="shareApp"
Android:title="@string/share_to_friends" />
<item
Android:id="@+id/fragment_about"
Android:icon="@drawable/ic_info"
Android:orderInCategory="5"
Android:title="@string/about" />
</menu>
Définissez d'abord une méthode onClick"shareApp" pour l'élément de menu "share_app". Ensuite, dans votre activité, créez une méthode comme celle-ci:
fun shareApp(item:MenuItem) {
logD("share app clicked!")
val intent = Intent(Intent.ACTION_SEND).apply {
putExtra(Intent.EXTRA_TEXT, "some text to send...")
type = "text/*"
}
startActivity(Intent.createChooser(intent, "Share app..."))
}
N'oubliez pas d'attacher une barre d'outils, NavigationView et DrawerLayout à NavController dans la méthode d'activité amusante onCreate (savedInstanceState: Bundle?) (Ou où vous voulez)
override fun onCreate(savedInstanceState: Bundle?) {
setTheme(R.style.AppTheme)
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
setupActionBarWithNavController(navController, drawer_layout)
setupWithNavController(nav_view, navController)
setupWithNavController(toolbar, navController, drawer_layout)
}