我在做什么?
我一直在尝试使用Androidx导航抽屉(<com.google.android.material.navigation.NavigationView>
)。我已经阅读了文档Here,该文档指出,为了处理项目选择,我们可以使用setNavigationItemSelectedListener
。
注意:我也正在使用JetPack的导航组件。
以下是: 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>
这里是: 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();
}
}
}
情况:
一切正常,我在运行时得到了Drawer
,也得到了Hamburger
,可以很好地显示带有菜单项的NavigationView
。
以下是: drawer_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>
问题:
在点击菜单项时,它不会响应我的点击事件,也就是onNavigationItemSelected
。如您所见,我的MainActivity.java
不会出现Toast
,开关内的任何菜单ID都不会起作用。
我一直在尝试许多示例和不同的方法来完成此操作。
有什么方法可以使菜单项响应我的选择事件?
如果您需要更多详细信息,请在下面做评论。
非常感谢您的帮助。
答案 0 :(得分:4)
我想通了。
以防万一有人需要,我将其发布在这里。
代替此:
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);
我更改为:
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;
}
});
它奏效了,可能是我们需要在附加onNavigationSelector
之前配置所有内容。
答案 1 :(得分:4)
如果有人仍在寻找答案,那么如何兼得两者:NavigationController既可以处理NavigationView项目,又可以在NavigationView内部进行一些特定的操作。
通常在menu.xml文件设置菜单项中:
<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>
首先为“ share_app” 菜单项定义 onClick 方法“ shareApp” 。然后在您的活动中创建如下所示的方法:
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..."))
}
不要忘记在活动(或任何需要的地方)的onCreate(savedInstanceState:Bundle?)方法重写乐趣中将工具栏,NavigationView和DrawerLayout附加到NavController
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)
}
答案 2 :(得分:1)
您可能还不了解切换订单的全部副作用。
NavigationUI.setupWithNavController(navigationView, navController); // Line 1
navigationView.setNavigationItemSelectedListener({...}) // Line 2
NavigationUI
内部在NavigationView.OnNavigationItemSelectedListener
处将NavigationView
附加到Line1
。您正在Line 2
中用自定义监听器覆盖该监听器。
这意味着navController
不起作用,您必须在自定义侦听器中手动处理所有导航操作。因此,完整的解决方案可能类似于以下方面:
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;
}
});
注意:
您可能仍想在附加自定义侦听器之前先调用setupWithNavController
,因为它除了附加导航项单击侦听器外,还执行其他操作。
答案 3 :(得分:0)
尝试一下,我希望这是一个完美的解决方案。只需编写以下代码即可导航到您的片段。
@Override
protected void onCreate(Bundle savedInstanceState) {
..........
..........
navigationView.setNavigationItemSelectedListener(this);
}
@Override
public boolean onNavigationItemSelected(@NonNull MenuItem menuItem) {
menuItem.setChecked(true);
drawerLayout.closeDrawers();
int id = menuItem.getItemId();
switch (id) {
case R.id.first:
navController.navigate(R.id.firstFragment);// **firstFragment** is the id that is written the file under **res/navigation/mobile_navigation.xml**
break;
case R.id.second:
navController.navigate(R.id.secondFragment);
break;
case R.id.third:
navController.navigate(R.id.thirdFragment);
break;
}
return true;
}
答案 4 :(得分:0)
MainActivity应该实现OnNavigationItemSelectedListener,您的代码应类似于
public class MainActivity extends AppCompatActivity implements NavigationView.OnNavigationItemSelectedListener{
...
}
答案 5 :(得分:0)
正确的顺序
navView.setupWithNavController(navController)
navView.setNavigationItemSelectedListener {
Log.e(TAG, "onCreate: ", )
true
}
如果不先执行 navView.setupWithNavController
,NavView.setNavigationItemSelectedListener
不会生效。