想在工具栏项目点击时进行片段转换

huangapple go评论82阅读模式
英文:

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 -

&lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot;?&gt;
&lt;androidx.coordinatorlayout.widget.CoordinatorLayout xmlns:android=&quot;http://schemas.android.com/apk/res/android&quot;
    xmlns:app=&quot;http://schemas.android.com/apk/res-auto&quot;
    android:id=&quot;@+id/container&quot;
    android:layout_width=&quot;match_parent&quot;
    android:layout_height=&quot;match_parent&quot;&gt;


    &lt;fragment
        android:id=&quot;@+id/nav_host_fragment&quot;
        android:name=&quot;androidx.navigation.fragment.NavHostFragment&quot;
        android:layout_width=&quot;match_parent&quot;
        android:layout_height=&quot;match_parent&quot;
        android:layout_marginBottom=&quot;?attr/actionBarSize&quot;
        app:defaultNavHost=&quot;true&quot;
        app:navGraph=&quot;@navigation/mobile_navigation&quot; /&gt;


    &lt;com.google.android.material.bottomnavigation.BottomNavigationView
        android:layout_gravity=&quot;bottom&quot;
        android:id=&quot;@+id/nav_view&quot;
        android:layout_width=&quot;match_parent&quot;
        android:layout_height=&quot;wrap_content&quot;
        android:background=&quot;?android:attr/windowBackground&quot;
        app:menu=&quot;@menu/bottom_nav_menu&quot; /&gt;

&lt;/androidx.coordinatorlayout.widget.CoordinatorLayout&gt;

To tie destination toolbar menu item to destination, you can simply put same id as your fragment in your navGraph

toolbar_menu.xml

&lt;menu xmlns:android=&quot;http://schemas.android.com/apk/res/android&quot;&gt;

    ...

    &lt;item
        android:id=&quot;@+id/setting_fragment&quot;
        android:icon=&quot;@drawable/ic_details&quot;
        android:title=&quot;@string/details&quot; /&gt;
&lt;/menu&gt;

mobile_navigation.xml (navGraph)

&lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot;?&gt;
&lt;navigation xmlns:app=&quot;http://schemas.android.com/apk/res-auto&quot;
    xmlns:tools=&quot;http://schemas.android.com/tools&quot;
    xmlns:android=&quot;http://schemas.android.com/apk/res/android&quot;
    ... &gt;
    ...

    &lt;fragment android:id=&quot;@+id/setting_fragment&quot;
         android:label=&quot;@string/setting&quot;
         android:name=&quot;com.example.android.myapp.SettingFragment&quot; /&gt;
&lt;/navigation&gt;

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 !

huangapple
  • 本文由 发表于 2020年8月13日 08:04:01
  • 转载请务必保留本文链接:https://go.coder-hub.com/63386202.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定