web-dev-qa-db-ja.com

フラグメントのAndroidオプションメニュー

フラグメントのグループからオプションメニューに項目を追加しようとしています。

私は新しいMenuFragmentクラスを作成し、メニュー項目を含めたいフラグメントのためにこれを拡張しました。コードは次のとおりです。

public class MenuFragment extends Fragment {

    MenuItem fav;

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

    public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
        fav = menu.add("add");
        fav.setIcon(R.drawable.btn_star_big_off);
    }
}

何らかの理由でonCreateOptionsMenuが実行されていないようです。

361
misterbassman

スーパーメソッドを呼び出します。

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

@Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
    // TODO Add your menu entries here
    super.onCreateOptionsMenu(menu, inflater);
}

メソッドが呼び出されていないかどうか、またはメニューがコードによって修正されていないかどうかを確認するために、ログステートメントをコードに入れます。

また、SetHasOptionsMenuonCreateを呼び出して、オプションメニューの処理に参加するようにフラグメントに通知するようにしてください。

558
Kuffs

私は同じ問題を抱えていました、しかし私はそれを動かすために最後のステップを要約して紹介することがより良いと思います:

  1. FragmentのonCreate(Bundle savedInstanceState)メソッドにsetHasOptionsMenu(true)メソッドを追加します。

  2. あなたのフラグメントのonCreateOptionsMenu(Menu menu, MenuInflater inflater)(あなたがあなたのフラグメントのメニューで何か別のことをしたいのであれば)とonOptionsItemSelected(MenuItem item)メソッドをオーバーライドします。

  3. onOptionsItemSelected(MenuItem item)アクティビティのメソッド内で、メニュー項目のアクションがonOptionsItemSelected(MenuItem item) Fragmentのメソッドに実装される場合は、必ずfalseを返すようにしてください。

例:

アクティビティ

@Override
public boolean onCreateOptionsMenu(Menu menu) {
    MenuInflater inflater = getSupportMenuInflater();
    inflater.inflate(R.menu.main, menu);
    return true;
}

@Override
public boolean onOptionsItemSelected(MenuItem item) {
    switch (item.getItemId()) {

        case R.id.activity_menu_item:

            // Do Activity menu item stuff here
            return true;

        case R.id.fragment_menu_item:

            // Not implemented here
            return false;
        default:
            break;
    }

    return false;
}

フラグメント

public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setHasOptionsMenu(true);
    ....
}

@Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
    // Do something that differs the Activity's menu here
    super.onCreateOptionsMenu(menu, inflater);
}

@Override
public boolean onOptionsItemSelected(MenuItem item) {
    switch (item.getItemId()) {

        case R.id.activity_menu_item:

            // Not implemented here
            return false;
        case R.id.fragment_menu_item:

            // Do Fragment menu item stuff here
            return true;

        default:
            break;
    }

    return false;
}
182
Marco HC

onCreateOptionsMenu(Menu menu, MenuInflater inflater)メソッドが呼び出されていないことがわかった場合は、フラグメントのonCreate(Bundle savedInstanceState)メソッドから必ず以下を呼び出してください。

setHasOptionsMenu(true)
152

私の場合は、使用した特定のwebview内のFragmentを更新するためのメニューが必要でした。

フラグメント

public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setHasOptionsMenu(true);
}

@Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {

    // TODO Add your menu entries here
    inflater.inflate(R.menu.menu, menu);
    super.onCreateOptionsMenu(menu, inflater);
}

@Override
public boolean onOptionsItemSelected(MenuItem item) {
    switch (item.getItemId()) {
    case R.id.exit:
        System.exit(1);
        break;

    case R.id.refresh:
        webView.reload();
        break;
    }
    return true;

}

menu.xml

<menu xmlns:Android="http://schemas.Android.com/apk/res/Android">
    <item Android:id="@+id/exit" Android:title="Exit" Android:icon="@drawable/ic_action_cancel" />
    <item Android:id="@+id/refresh" Android:title="Refresh" Android:icon="@drawable/ic_action_refresh" />
</menu>
48
Pedro Lobito

menu.xmlでは、すべてのメニュー項目を追加する必要があります。そうすれば、初期ロードで見たくないアイテムを隠すことができます。

menu.xml

<item
    Android:id="@+id/action_newItem"
    Android:icon="@drawable/action_newItem"
    Android:showAsAction="never"
    Android:visible="false"
    Android:title="@string/action_newItem"/>

Fragmentクラスのメニュー項目を呼び出すには、onCreate()メソッドにsetHasOptionsMenu(true)を追加します。

FragmentClass.Java

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

FragmentクラスでonCreateOptionsMenuをオーバーライドする必要はもうありません。 Fragmentで利用可能なonPrepareOptionsMenumethodをオーバーライドすることによってメニュー項目を変更(追加/削除)することができます。

@Override
public void onPrepareOptionsMenu(Menu menu) {
    menu.findItem(R.id.action_newItem).setVisible(true);
    super.onPrepareOptionsMenu(menu);

}
23

メニューを膨らませる前にmenu.clear()を使う必要があります。

@Override
    public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
        menu.clear();
        inflater.inflate(R.menu.menu, menu);
        super.onCreateOptionsMenu(menu, inflater);
    }

そして

@Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setHasOptionsMenu(true);
    }
16
Spl2nky

TL、DR

Android.support.v7.widget.Toolbarを使用して、ただしてください:

toolbar.inflateMenu(R.menu.my_menu)
toolbar.setOnMenuItemClickListener {
    onOptionsItemSelected(it)
}

スタンドアロンツールバー

setHasOptionsMenu(true)のような提案された解決策のほとんどは 親アクティビティがそのレイアウトに - ツールバーを持っていて - setSupportActionBar()を通してそれを宣言するときにだけ働いています。それからフラグメントは、この正確な ActionBar のメニュー作成に参加することができます。

Fragment.onCreateOptionsMenu():Fragment Hostの標準オプションメニューの内容を初期化します。

ある特定のフラグメント用のスタンドアロンのツールバーとメニューが必要な場合 次の操作を実行できます。

menu_custom_fragment.xml

<menu xmlns:Android="http://schemas.Android.com/apk/res/Android"
xmlns:app="http://schemas.Android.com/apk/res-auto">
    <item
        Android:id="@+id/menu_save"
        Android:title="SAVE" />
</menu>

custom_fragment.xml

<FrameLayout xmlns:Android="http://schemas.Android.com/apk/res/Android"
    Android:layout_width="match_parent"
    Android:layout_height="match_parent">

    <Android.support.v7.widget.Toolbar
        Android:id="@+id/toolbar"
        Android:layout_width="match_parent"
        Android:layout_height="wrap_content" />

    ...

CustomFragment.kt

override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
    val view = inflater.inflate(layout.custom_fragment, container, false)
    val toolbar = view.findViewById<Toolbar>(R.id.toolbar)
    toolbar.inflateMenu(R.menu.menu_custom_fragment)
    toolbar.setOnMenuItemClickListener {
        onOptionsItemSelected(it)
    }
    return view
}

override fun onOptionsItemSelected(item: MenuItem): Boolean {
    return when (item.itemId) {
        R.id.menu_save -> {
            // TODO: User clicked the save button
            true
        }
        else -> super.onOptionsItemSelected(item)
    }
}

はい、それはとても簡単です。 onCreate()onCreateOptionsMenu()をオーバーライドする必要すらありません。

シモンズ:これはAndroid.support.v4.app.FragmentAndroid.support.v7.widget.Toolbarでのみ働いています(あなたのstyles.xmlAppCompatActivityAppCompatテーマも必ず使ってください)。

10
Marius

私の場合は、ここに手順があります。

ステップ1

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

    // Here notify the fragment that it should participate in options menu handling.
    setHasOptionsMenu(true);
}

ステップ2

@Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
    // First clear current all the menu items
    menu.clear();

    // Add the new menu items
    inflater.inflate(R.menu.post_stuff, menu);

    super.onCreateOptionsMenu(menu, inflater);
}

ステップ-3

 @Override
public boolean onOptionsItemSelected(MenuItem item) {
    switch (item.getItemId()) {
        case R.id.post_stuff:
            Log.d(TAG, "Will post the photo to server");
            return true;
        case R.id.cancel_post:
            Log.d(TAG, "Will cancel post the photo");
            return true;
        default:
            break;
    }
    return super.onOptionsItemSelected(item);
}
9
Harry Zhang

私は同じ問題を抱えていました、私の断片はViewPagerのページでした。それが起こっていたのは、FragmentPagerAdapterをインスタンス化するときに、アクティビティサポートフラグメントマネージャではなく子フラグメントマネージャを使用していたためです。

7
farid_z

メニューカスタムを追加したい場合

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

@Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
    inflater.inflate(R.menu.menu_custom, menu);
}
6

あなたのコードは大丈夫です。メソッドにスーパーだけが欠けていました:

@Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
    // TODO add your menu : 
    inflater.inflate(R.menu.my_menu, menu);
    //TODO call super
    super.onCreateOptionsMenu(menu, inflater);
}
3
AlexPad

メニューファイル

<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:Android="http://schemas.Android.com/apk/res/Android">
    <item
        Android:id="@+id/play"
        Android:titleCondensed="Speak"
        Android:showAsAction="always"
        Android:title="Speak"
        Android:icon="@drawable/ic_play">
    </item>
    <item
        Android:id="@+id/pause"
        Android:titleCondensed="Stop"
        Android:title="Stop"
        Android:showAsAction="always"
        Android:icon="@drawable/ic_pause">
    </item>
</menu>

活動コード

@Override
public boolean onCreateOptionsMenu(Menu menu) {
    MenuInflater inflater = getMenuInflater();
    inflater.inflate(R.menu.speak_menu_history, menu);
    return true;
}

@Override
public boolean onOptionsItemSelected(MenuItem item) {
    switch (item.getItemId()) {

        case R.id.play:
            Toast.makeText(getApplicationContext(), "speaking....", Toast.LENGTH_LONG).show();
            return false;

        case R.id.pause:
            Toast.makeText(getApplicationContext(), "stopping....", Toast.LENGTH_LONG).show();
            return false;

        default:
            break;
    }

    return false;
}

フラグメントコード:

@Override

public void onCreate(Bundle savedInstanceState) {
    // TODO Auto-generated method stub
    super.onCreate(savedInstanceState);
    setHasOptionsMenu(true);
}

@Override
public boolean onOptionsItemSelected(MenuItem item) {
    switch (item.getItemId()) {

        case R.id.play:
            text = page.getText().toString();
            speakOut(text);

            // Do Activity menu item stuff here
            return true;

        case R.id.pause:
            speakOf();

            // Not implemented here
            return true;

        default:
            break;
    }
    return false;
}
3
Suyog Gunjal

ここで答えがどれも私のために働かなかったので、私は狂っていました。

呼び出さなければならないメニューを表示するには setSupportActionBar(toolbar)

完了しました。

注:toolbarビューが同じアクティビティレイアウトにない場合は、アクティビティクラスから直接上記の呼び出しを使用することはできません。この場合、フラグメントクラスからそのアクティビティを取得してsetSupportActionBar(toolbar)を呼び出す必要があります。覚えておいてください:あなたの活動クラスはAppCompatActivityを拡張するべきです。

この答えがあなたのお役に立てばと思っています。

フラグメントビューを作成した後にオプションメニューを設定することは私にとってうまくいった。

@Override
public void onActivityCreated(Bundle savedInstanceState) {
    super.onActivityCreated(savedInstanceState);
    setHasOptionsMenu(true);        
}
1
Jerry Frost

あなたのメニューフォルダに.menu xmlファイルを作り、このxmlを追加

<item
    Android:id="@+id/action_search"
    Android:icon="@Android:drawable/ic_menu_search"
    Android:title="@string/action_search"
    app:actionViewClass="Android.support.v7.widget.SearchView"
    app:showAsAction="always|collapseActionView" />

あなたのフラグメントクラスでこのメソッドをオーバーライドして

implement SearchView.OnQueryTextListener    in your fragment class



@Override
 public void onViewCreated(View view, Bundle savedInstanceState) {    
  super.onViewCreated(view, savedInstanceState);
  setHasOptionsMenu(true);

}

フラグメントクラスでメニューxmlファイルを設定するだけです。

@Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
    inflater.inflate(R.menu.menu_main, menu);

    final MenuItem item = menu.findItem(R.id.action_search);
    final SearchView searchView = (SearchView)    
    MenuItemCompat.getActionView(item);


    MenuItemCompat.setOnActionExpandListener(item,
            new MenuItemCompat.OnActionExpandListener() {
                @Override
                public boolean onMenuItemActionCollapse(MenuItem item) {
                    // Do something when collapsed

                    return true; // Return true to collapse action view
                }

                @Override
                public boolean onMenuItemActionExpand(MenuItem item) {
                    // Do something when expanded
                    return true; // Return true to expand action view
                }
            });

}
1
pavel

私の問題は少し違っていました。私はすべてうまくいった。しかし、私はフラグメントをホストしているアクティビティのために間違ったクラスを継承していました。

そのため、フラグメント内でonCreateOptionsMenu(Menu menu, MenuInflater inflater)をオーバーライドする場合は、このフラグメントをホストするアクティビティクラスがAndroid.support.v7.app.ActionBarActivityを継承していることを確認してください(APIレベル11以下をサポートする場合)。

私は11以下のAPIレベルをサポートするためにAndroid.support.v4.app.FragmentActivityを継承していました。

1
Krishna Deepak

私がこれに追加する1つのことと、それが私にとってうまくいかなかった理由.

それはナップスターの答えに似ています。

  1. フラグメントのホスティングアクティビティがAppCompatActivityではなくFragmentActivityに及ぶことを確認してください。

    public class MainActivity extends AppCompatActivity {
    
    }
    

    Googleリファレンスから ドキュメント FragmentActivityの場合:

    注:アクションバーを含むアクティビティを実装する場合は、代わりにこのクラスのサブクラスであるActionBarActivityクラスを使用する必要があります。そのため、APIレベル7以降でFragment APIを使用できます。

  2. Napsterの答え - ActionBarActivityが非推奨になったのを更新するには、代わりにAppCompatActivityを使用してください。

  3. AppCompatActivityを使用するときは、必ず「アクティビティのテーマをTheme.AppCompatまたは類似のテーマ」に設定してください(Google Doc)。

注:Android.support.v7.app.AppCompatActivityAndroid.support.v4.app.FragmentActivityクラスのサブクラスです( AppCompatActivity ref docを参照)。

1
bastien

上記のすべてが機能しない場合は、デバッグして、関数onCreateOptionsMenuが呼び出されていることを確認する必要があります(debugまたはwrite log ...を配置して)。

実行されない場合は、Androidテーマがアクションバーをサポートしていない可能性があります。 AndroidManifest.xmlを開き、テーマサポートのアクションバーでAndroid:themeの値を設定します

 <activity
     Android:name=".MainActivity"
     Android:label="@string/app_name"
     Android:theme="@style/Theme.AppCompat">
0
Grey Wolf

on onCreate method add setHasOptionMenu()

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

それから オーバーライド your onCreateOptionsMenu

@Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
    menu.add("Menu item")
            .setIcon(Android.R.drawable.ic_delete)
            .setShowAsAction(MenuItem.SHOW_AS_ACTION_IF_ROOM);
}
0
Ashana.Jackol