特定の Fragment でだけ使うメニュー項目を共用の Toolbar に inflate する
概要
Activity が持つ Toolbar の Overflow メニューに、特定の Fragment だけで使うメニュー項目を挿入する方法を考えてみました。
背景
Toolbar を持つ Activity で、 Fragment A と Fragment B を入れ替えます。Activity で Toolbar に inflate したメニュー項目は Fragment A/B 両方で表示されるので、Fragment A でしか必要のないメニューは Fragment A を表示しているときだけ出したい、と思いました。
実行環境
項目 | 値 |
---|---|
Android OS | 4.3 |
compileSdkVersion | 25 |
buildToolsVersion | "25.0.3" |
よりよい実装方法はこちら
実装
onCreateView で menu を inflate し、onDetach で挿入した menu を削除するというやり方でやってみました。menu を挿入・削除する対象の Toolbar は getActivity() して取得できる Activity オブジェクトから findViewById して取得しています。
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentActivity;
import android.support.v4.graphics.ColorUtils;
import android.support.v7.widget.Toolbar;
public class FragmentA extends Fragment {
//...
@Nullable
@Override
public View onCreateView(
final LayoutInflater inflater,
@Nullable final ViewGroup container,
@Nullable final Bundle savedInstanceState
) {
//...
inflateMenuToToolbar();
}
private void inflateMenuToToolbar() {
final FragmentActivity activity = getActivity();
final Toolbar toolbar = (Toolbar) activity.findViewById(R.id.toolbar);
toolbar.inflateMenu(R.menu.fragment_a_menu);
// チェックするタイプのメニューだったらチェックを入れる.
// toolbar.getMenu().findItem(R.id.menu_checkable).setChecked(checked);
toolbar.setOnMenuItemClickListener(item -> {
if (item.getItemId() == R.id.menu_checkable) {
// メニューがタップされた時の処理をここに記述.
return true;
}
// Activity が持つメニューを呼び出す.
return activity.onOptionsItemSelected(item);
});
}
//...
@Override
public void onDetach() {
super.onDetach();
final Toolbar toolbar = (Toolbar) getActivity().findViewById(R.id.toolbar);
toolbar.getMenu().removeItem(R.id.menu_checkable);
}
微妙な点
- Activity の Toolbar の ID を持つ(あるいは Activity クラスの public 定数として定義する)ようにしないといけない
- Activity が Toolbar を持っているかどうか、null チェックするくらいしか確認する方法がない
- 挿入した menu を逐一 onDetach で削除しないといけない
おわりに
やってみたところ、実装はできましたが、あまり良いやり方に感じませんでした。よりよい方法をご存知でしたらお教えくださいますと幸いです。
参考
下記ブログの方法を参考に致しました。
- AndroidのFragmentでActivityのToolbarを利用する
追記
上で私が微妙だと書いた点がすべて解消されている最適なやり方を、roana0229 さんからコメントで教えていただいたので、そちらの方法で修正しました。
1. Toolbar を持つ Activity で setSupportActionBar する
@Override
protected void onCreate(final Bundle savedInstanceState) {
// ...
setSupportActionBar(binding.appBarMain.toolbar);
}
2. Fragment 固有のメニューを inflate する
onCreateView で setHasOptionsMenu(true);
を呼び、 onCreateOptionsMenu で inflate します。
@Nullable
@Override
public View onCreateView(
final LayoutInflater inflater,
@Nullable final ViewGroup container,
@Nullable final Bundle savedInstanceState
) {
// ...
setHasOptionsMenu(true);
}
@Override
public void onCreateOptionsMenu(final Menu menu, final MenuInflater inflater) {
super.onCreateOptionsMenu(menu, inflater);
inflater.inflate(R.menu.search_menu, menu);
final MenuItem item = menu.findItem(R.id.menu_checkable);
// チェックするタイプのメニューだったらチェックを入れる.
// item.setChecked(checked);
item.setOnMenuItemClickListener(i -> {
// メニューがタップされた時の処理をここに記述.
return true;
});
}
Author And Source
この問題について(特定の Fragment でだけ使うメニュー項目を共用の Toolbar に inflate する), 我々は、より多くの情報をここで見つけました https://qiita.com/toastkidjp/items/c56594c09725c54af6b1著者帰属:元の著者の情報は、元のURLに含まれています。著作権は原作者に属する。
Content is automatically searched and collected through network algorithms . If there is a violation . Please contact us . We will adjust (correct author information ,or delete content ) as soon as possible .