英文:
Want to make a fragment transition on an toolbar item click
问题
I want to transition to the setting fragment when the user clicks the settings button on the toolbar, but I have been trying to make a fragment transition from the onOptionsItemSelected() but I've not been able to do it.
当用户在工具栏上点击设置按钮时,我想要过渡到设置片段,但我一直在尝试从onOptionsItemSelected()进行片段过渡,但我一直无法成功。
I also have a navigation controller, but I can't find a way to access it from the onOptionsSelected() to make the transition, which I use for every other fragment transition.
我还有一个导航控制器,但我无法找到一种方法从onOptionsSelected()访问它以进行过渡,尽管我在其他所有片段过渡中都使用它。
Can you tell me what I'm doing wrong?
你能告诉我我做错了什么吗?
英文:
I want to transition to the setting fragment when the user clicks the settings button on the toolbar, but I have been trying to make a fragment transition from the onOptionsItemSelected() but I've not been able to do it.
I also a a navigation controller, but I can't find a way to access it from the onOptionsSelected() to make the transition, which I use for every other fragment transition.
Can you tell me what I'm doing wrong?
Thanks
public class MainActivity extends AppCompatActivity {
BottomNavigationView bottomNavigationView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Toolbar toolbar = findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
setUpNavigation();
}
//bottom bar navigation set up
public void setUpNavigation(){
bottomNavigationView = findViewById(R.id.bottom_navigation);
NavHostFragment navHostFragment = (NavHostFragment)getSupportFragmentManager().findFragmentById(R.id.nav_host_fragment);
NavigationUI.setupWithNavController(bottomNavigationView, navHostFragment.getNavController());
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.toolbar_menu, menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()){
case R.id.nav_settings:
Toast.makeText(getApplicationContext(), "Settings Selected", Toast.LENGTH_SHORT).show();
Log.d("debug","fragment: action settings was clicked");
getSupportFragmentManager().beginTransaction().replace(R.id.nav_host_fragment, new SettingsFragment()).addToBackStack(null).commit();
return true;
}
return super.onOptionsItemSelected(item);
}
}
</details>
# 答案1
**得分**: 0
如果您正在使用[Android Jetpack的导航组件][1],那么您不应该使用FragmentMangaer来导航到片段。
请按以下方式查找NavController -
```java
// 在此处将其作为全局变量
NavController navController;
public void setUpNavigation(){
// 查找NavController
navController = Navigation.findNavController(this, R.id.nav_host_fragment);
// 使用NavController设置工具栏
AppBarConfiguration appBarConfiguration = new AppBarConfiguration.Builder(navController.getGraph()).build();
NavigationUI.setupActionBarWithNavController(this, navController, appBarConfiguration);
// 设置底部导航视图
bottomNavigationView = findViewById(R.id.bottom_navigation);
NavigationUI.setupWithNavController(bottomNavigationView, navController);
}
如果您注意到在查找NavController时使用了R.id.nav_host_fragment
,那么它将与activity_main.xml
中的主机片段的相同ID匹配,如下所示 -
<?xml version="1.0" encoding="utf-8"?>
<androidx.coordinatorlayout.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/container"
android:layout_width="match_parent"
android:layout_height="match_parent">
<fragment
android:id="@+id/nav_host_fragment"
android:name="androidx.navigation.fragment.NavHostFragment"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginBottom="?attr/actionBarSize"
app:defaultNavHost="true"
app:navGraph="@navigation/mobile_navigation" />
<com.google.android.material.bottomnavigation.BottomNavigationView
android:layout_gravity="bottom"
android:id="@+id/nav_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="?android:attr/windowBackground"
app:menu="@menu/bottom_nav_menu" />
</androidx.coordinatorlayout.widget.CoordinatorLayout>
要将目标工具栏菜单项与目标关联,您可以简单地使用与您的片段相同的ID放置在navGraph中,如下所示:
toolbar_menu.xml
<menu xmlns:android="http://schemas.android.com/apk/res/android">
...
<item
android:id="@+id/setting_fragment"
android:icon="@drawable/ic_details"
android:title="@string/details" />
</menu>
mobile_navigation.xml (navGraph)
<?xml version="1.0" encoding="utf-8"?>
<navigation xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
xmlns:android="http://schemas.android.com/apk/res/android">
...
...
<fragment android:id="@+id/setting_fragment"
android:label="@string/setting"
android:name="com.example.android.myapp.SettingFragment" />
</navigation>
请注意,我们为菜单项和navGraph都分配了setting_fragment
ID。
然后,您可以像下面这样重写onOptionsItemSelected
方法 -
@Override
public boolean onOptionsItemSelected(MenuItem item) {
NavController navController = Navigation.findNavController(this, R.id.nav_host_fragment);
return NavigationUI.onNavDestinationSelected(item, navController)
|| super.onOptionsItemSelected(item);
}
如果您没有使用NoActionBar样式,那么在活动的onCreate()
中创建工具栏是没有必要的,因为Android会为您创建一个工具栏 -
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// 如果样式不是NoActionBar,则无需创建工具栏
// Toolbar toolbar = findViewById(R.id.toolbar);
// setSupportActionBar(toolbar);
setUpNavigation();
}
欲了解更多信息,请参阅使用NavigationUI更新UI组件。
愉快的编码!
英文:
If you are using Android Jetpack's Navigation component then you should not use FragmentMangaer to navigate to fragments.
Find navController as follows -
//taking as a global variable here
NavController navController;
public void setUpNavigation(){
//find NavController
navController = Navigation.findNavController(this, R.id.nav_host_fragment);
//setting up Toolbar with NavController
AppBarConfiguration appBarConfiguration = new AppBarConfiguration.Builder(navController.getGraph()).build();
NavigationUI.setupActionBarWithNavController(this, navController, appBarConfiguration);
//setting up bottomNavigationView
bottomNavigationView = findViewById(R.id.bottom_navigation);
NavigationUI.setupWithNavController(bottomNavigationView, navController);
}
If you notice R.id.nav_host_fragment
while finding navController, it will be the same id of host fragment under activity_main.xml
as follow -
<?xml version="1.0" encoding="utf-8"?>
<androidx.coordinatorlayout.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/container"
android:layout_width="match_parent"
android:layout_height="match_parent">
<fragment
android:id="@+id/nav_host_fragment"
android:name="androidx.navigation.fragment.NavHostFragment"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginBottom="?attr/actionBarSize"
app:defaultNavHost="true"
app:navGraph="@navigation/mobile_navigation" />
<com.google.android.material.bottomnavigation.BottomNavigationView
android:layout_gravity="bottom"
android:id="@+id/nav_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="?android:attr/windowBackground"
app:menu="@menu/bottom_nav_menu" />
</androidx.coordinatorlayout.widget.CoordinatorLayout>
To tie destination toolbar menu item to destination, you can simply put same id as your fragment in your navGraph
toolbar_menu.xml
<menu xmlns:android="http://schemas.android.com/apk/res/android">
...
<item
android:id="@+id/setting_fragment"
android:icon="@drawable/ic_details"
android:title="@string/details" />
</menu>
mobile_navigation.xml (navGraph)
<?xml version="1.0" encoding="utf-8"?>
<navigation xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
xmlns:android="http://schemas.android.com/apk/res/android"
... >
...
<fragment android:id="@+id/setting_fragment"
android:label="@string/setting"
android:name="com.example.android.myapp.SettingFragment" />
</navigation>
Notice we given id setting_fragment
to menu item and setting fragment in navGraph as well.
then you can override onOptionsItemSelected
as follows -
@Override
public boolean onOptionsItemSelected(MenuItem item) {
NavController navController = Navigation.findNavController(this, R.id.nav_host_fragment);
return NavigationUI.onNavDestinationSelected(item, navController)
|| super.onOptionsItemSelected(item);
}
And if you not using style as NoActionBar, then there is no need to create toolbar in activity onCreate()
because android will create a toolbar for you-
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//no need to create a toolbar if style is not NoActionBar
//Toolbar toolbar = findViewById(R.id.toolbar);
//setSupportActionBar(toolbar);
setUpNavigation();
}
For more information please follow Update UI components with NavigationUI
Happy Coding !
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论