web-dev-qa-db-ja.com

ナビゲーションコンポーネントを備えたトップアプリバーとボトムアプリバーの2つの異なるメニュー

Android Navigation Architecture Component )を試していて、 マテリアルデザイン ガイドラインも調べていました。 (デザイン 以下:

Top and bottom app bar

上部のツールバーについては、setSupportActionBar(toolbar)で設定してからMainActivityで設定できます。

_public boolean onCreateOptionsMenu(Menu menu) {
    getMenuInflater().inflate(R.menu.menu, menu);
    return super.onCreateOptionsMenu(menu);
}
_

しかし、試してみると、さまざまなフラグメント、特に下部のアプリバーに対して、上部と下部の両方のアプリバーにメニューを実装する方法がわかりません。

たとえば下部のアプリバーにのみお気に入りのアイコンを表示したいDetailFragmentでは、ただしMainActivityでは、削除する必要があります。

私の現在のコード:

MainActivity

_public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Toolbar toolbar = findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);

        NavController navController = Navigation.findNavController(this, R.id.nav_Host);
        NavigationUI.setupActionBarWithNavController(this, navController);


        FloatingActionButton fab = findViewById(R.id.fab);
        fab.setOnClickListener(view -> Snackbar.make(view, "Replace with your own action", Snackbar.LENGTH_LONG)
                .setAction("Action", null).show());


    }

    @Override
    public boolean onSupportNavigateUp() {
        return Navigation.findNavController(this, R.id.nav_Host).navigateUp();
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.menu, menu);
        return super.onCreateOptionsMenu(menu);
    }
}
_

MainFragment

_public class MainFragment extends Fragment {

    public MainFragment() {
        // Required empty public constructor
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        // Inflate the layout for this fragment
        return inflater.inflate(R.layout.fragment_main, container, false);
    }

    @Override
    public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
        super.onViewCreated(view, savedInstanceState);
        Button buttonOne = view.findViewById(R.id.button_one);
        buttonOne.setOnClickListener(Navigation.createNavigateOnClickListener(R.id.detailFragment));
    }

}
_

DetailFragment

_public class DetailFragment extends Fragment {

    public DetailFragment() {
        // Required empty public constructor
    }

    @Override
    public void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        // Inflate the layout for this fragment
        return inflater.inflate(R.layout.fragment_detail, container, false);
    }

    @Override
    public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
        super.onViewCreated(view, savedInstanceState);
    }
}
_

activity_main.xml

_<?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"
    xmlns:tools="http://schemas.Android.com/tools"
    Android:layout_width="match_parent"
    Android:layout_height="match_parent"
    Android:animateLayoutChanges="true"
    tools:context=".MainActivity">

    <com.google.Android.material.appbar.AppBarLayout
        Android:layout_width="match_parent"
        Android:layout_height="wrap_content"
        Android:animateLayoutChanges="true"
        Android:theme="@style/AppTheme.AppBarOverlay">

        <androidx.appcompat.widget.Toolbar
            Android:id="@+id/toolbar"
            Android:layout_width="match_parent"
            Android:layout_height="?attr/actionBarSize"
            Android:background="?attr/colorPrimary"
            app:popupTheme="@style/AppTheme.PopupOverlay" />

    </com.google.Android.material.appbar.AppBarLayout>

    <fragment
        Android:id="@+id/nav_Host"
        Android:name="androidx.navigation.fragment.NavHostFragment"
        Android:layout_width="match_parent"
        Android:layout_height="match_parent"
        Android:layout_gravity="top"
        Android:layout_marginTop="?android:attr/actionBarSize"
        app:defaultNavHost="true"
        app:layout_anchor="@id/bottom_appbar"
        app:layout_anchorGravity="top"
        app:layout_behavior="@string/appbar_scrolling_view_behavior"
        app:navGraph="@navigation/mobile_navigation" />

    <com.google.Android.material.bottomappbar.BottomAppBar
        Android:id="@+id/bottom_appbar"
        Android:layout_width="match_parent"
        Android:layout_height="?android:attr/actionBarSize"
        Android:layout_gravity="bottom" />

    <com.google.Android.material.floatingactionbutton.FloatingActionButton
        Android:id="@+id/fab"
        Android:layout_width="wrap_content"
        Android:layout_height="wrap_content"
        app:layout_anchor="@id/bottom_appbar" />

</androidx.coordinatorlayout.widget.CoordinatorLayout>
_

mobile_navigation.xml

_<navigation 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/mobile_navigation"
    app:startDestination="@id/mainFragment">
    <fragment
        Android:id="@+id/mainFragment"
        Android:name="com.example.MainFragment"
        Android:label="fragment_main"
        tools:layout="@layout/fragment_main" >
        <action
            Android:id="@+id/toAccountFragment"
            app:destination="@id/detailFragment" />
    </fragment>
    <fragment
        Android:id="@+id/detailFragment"
        Android:name="com.example.DetailFragment"
        Android:label="fragment_account"
        tools:layout="@layout/fragment_detail" />
</navigation>
_

menu.xml

_<menu xmlns:Android="http://schemas.Android.com/apk/res/Android"
    xmlns:app="http://schemas.Android.com/apk/res-auto">

    <item
        Android:id="@+id/app_bar_settings"
        Android:title="@string/action_settings"
        app:showAsAction="never" />
</menu>
_

bottom_appbar_menu.xmlfor DetialFragmentのみ

_<menu xmlns:Android="http://schemas.Android.com/apk/res/Android"
    xmlns:app="http://schemas.Android.com/apk/res-auto">

    <item
        Android:id="@+id/action_bottom_fav"
        Android:icon="@drawable/ic_favorite"
        Android:title="@string/action_favorite"
        app:showAsAction="ifRoom" />
</menu>
_

どんな助けでも大歓迎です。


可能な解決策で更新:

これは私が思いつくことができるものですが、それがそれを行うための書き込み方法であるかどうかわからないため、満足していません。私は可能な解決策を投稿しています:

1- MainActivity

_NavController navController = Navigation.findNavController(this, R.id.nav_Host);
NavigationUI.setupWithNavController(toolbar, navController);
_

2-下部のアプリバー用に2つの異なるメニューを作成します(メニュー項目を動的に追加しようとしませんでした)。1つはMainFragmentの空白のメニューxmlを使用し、もう1つはDetailFragmentのお気に入りのアイコンを含みます。 。

簡単にするために、onCreateOptionsMenuでオーバーライドするのではなくMainActivityMainFragmentをオーバーライドします。

_public boolean onCreateOptionsMenu(Menu menu) {
    getMenuInflater().inflate(R.menu.menu, menu);
    bottomAppBar.replaceMenu(R.menu.bottom_menu_blank);
    return super.onCreateOptionsMenu(menu);
}
_

3- Bottom AppBarのreplaceMenuメソッドについて教えてくれた @ʍѳђઽ૯ท に感謝します。 DetailFragmentsetHasOptionsMenu(true)を使用し、onCreateOptionsMenuをオーバーライドします。

_public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
    super.onCreateOptionsMenu(menu, inflater);
    BottomAppBar bottomAppBar = requireActivity().findViewById(R.id.bottom_appbar);
    bottomAppBar.replaceMenu(R.menu.bottom_menu_fav);
}
_

誰かがより良い方法を持っているなら、知らせてください。

6
Rajarshi

いつものようにToolbaronCreateOptionsMenu()を使用するだけです:(Kotlin

_override fun onCreateOptionsMenu(menu: Menu?): Boolean {
        menuInflater.inflate(R.menu.menu_first, menu)
        return super.onCreateOptionsMenu(menu)
    }
_

次に、onCreate()内でToolbarを宣言し、setSupportActionBar()を使用します。

_val toolbar = findViewById<Toolbar>(R.id.myToolbar)
setSupportActionBar(toolbar)
_

その後、replaceMenu()がトリックを実行します:(内部onCreate()

_val bottomBar = findViewById<BottomAppBar>(R.id.bottomAppBar)
bottomBar.replaceMenu(R.menu.menu_main)
_

BottomSheetFragmentの開始にNavigationViewを使用する場合、setSupportActionBarmenusを設定するには、BottomAppBarが必要ですが、これを修正する方法がまだ見つかりませんでした。

4
ʍѳђઽ૯ท

複数のツールバー(またはBottomAppBar)を使用するには、もう一方のツールバーを手動で膨らませる必要があります。 setSupportActionBar()およびonCreateOptionsMenu()を呼び出すと、基本的に次のようになります。

private boolean inflateBottomAppBar() {
    BottomAppBar bottomAppBar = findViewById(R.id.bottomAppBar);
    Menu bottomMenu = bottomAppBar.getMenu();
    getMenuInflater().inflate(R.menu.menu_bottom, bottomMenu);
    for (int i = 0; i < bottomMenu.size(); i++) {
        bottomMenu.getItem(i).setOnMenuItemClickListener(new MenuItem.OnMenuItemClickListener() {
            @Override
            public boolean onMenuItemClick(MenuItem menuItem) {
                return onOptionsItemSelected(menuItem);
            }
        });
    }
    return super.onCreateOptionsMenu(menu);
}

ここで、R.id.bottomAppBarBottomAppBarのIDであり、R.menu.menu_bottomはメニュー項目のIDです。

メインツールバーを膨らませた後、onCreateOptionsMenu()でこのメソッドを呼び出してください。すべてのアイテムのクリックは、onOptionsItemSelected()メソッドによって通常どおり処理されます。

これは、2つ以上の通常のツールバーを作成している場合にも機能します。

0
Jean Knapp