Fragment
を拡張し、setHasOptionsMenu
を呼び出してメニューに参加するフラグメントクラスがあります。このクラスは、onCreateOptionsMenu
、onPrepareOptionsMenu
、およびonOptionsItemSelected
も実装します。
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setHasOptionsMenu(true);
....
}
私のアクティビティでFragmentTransaction
を使用してこのフラグメントを動的にロードしています(FragmentActivity
を拡張しています)。
ただし、メニューコールバック(onCreateOptionsMenu
、onPrepareOptionsMenu
およびonOptionsItemSelected
)のいずれも呼び出されず(これらのメソッドにいくつかのブレークポイントを設定してデバッグしました)、メニューは表示されません。 。
何か不足していますか?アクティビティに何かを追加する必要がありますか?
Android互換性ライブラリを使用して、L11 SDKでコンパイルし、Xoomでテストしています。
[〜#〜] edit [〜#〜]:問題が見つかりました。私のAndroidManifestはL11をターゲットにしています。これによりメニューボタンが非表示になり、コールバックが呼び出されないように見えます。しかし、これをマニフェストから削除すると、必要な他の機能がいくつか失われます(たとえば、リストのアクティブ化された状態)。マニフェストからtargetSdkVersion=11
を削除せずにこの問題を解決する方法(メニューボタンを有効にする)を知っている人はいますか?
問題を見つけました。 AndroidManifestはSDK 11をターゲットにしているため、メニューボタンが非表示になり、コールバックが呼び出されないようになっています。これにより、Android 3.0でアクションバーに置き換えられたように見えるメニューボタンの互換性が損なわれると思います
Aromero、次のように、メソッドのフラグメントバージョンを使用してonCreateOptionsMenuをオーバーライドすることを忘れないでください。
@Override
public void onCreateOptionsMenu (Menu menu, MenuInflater inflater) {
inflater.inflate(R.menu.queue_options, menu);
super.onCreateOptionsMenu(menu, inflater);
}
ちなみに、これはフラグメントに含まれ、アクティビティがある場合は、そのメニューに追加されます。私がこれを理解するまで、私自身も同じ問題を抱えていました。
キム
私は同じ問題を抱えていましたが、それを機能させるための最後のステップを要約して紹介する方が良いと思います:
フラグメントのonCreate(Bundle savedInstanceState)
メソッドにsetHasOptionsMenu(true)メソッドを追加します。
onCreateOptionsMenu(Menu menu, MenuInflater inflater)
(Fragmentのメニューで別のことを実行したい場合)およびFragmentのonOptionsItemSelected(MenuItem item)
メソッドをオーバーライドします。
onOptionsItemSelected(MenuItem item)
アクティビティのメソッド内で、メニュー項目アクションがonOptionsItemSelected(MenuItem item)
フラグメントのメソッドに実装される場合は、必ず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) {
// 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;
}
これがお役に立てば幸いです。
乾杯。
ActionBarSherlockでこの問題が発生している場合は、フラグメントが単なるSupportFragmentsではなくSherlockFragmentsであること、およびオーバーライドしているものが
public void onPrepareOptionsMenu (com.actionbarsherlock.view.Menu menu) {
ない
public void onPrepareOptionsMenu (Android.view.Menu menu) {
後者を実行すると、関数が最終的であり、それをオーバーライドできないことについて、何らかの警告が表示されます。これは、間違った関数をオーバーライドしようとしているという警告です!
クラスをSherlockFragmentから単なるFragmentに切り替えることでエラーを修正すると、関数を作成できます。 。 。呼び出されません。
それぞれがメニュー項目をロードするアクティビティとフラグメントがある場合は、使用するオーバーライドに特別な注意を払う必要があります。
アクティビティはonOptionsItemSelectedおよびonMenuItemSelectedをオーバーライドできますが、フラグメントはonOptionsItemSelectedのみをオーバーライドできます。
アクティビティでonMenuItemSelectedをオーバーライドし、フラグメントでonOptionsItemSelectedをオーバーライドした場合、フラグメントオーバーライドはトリガーされません。
代わりに、アクティビティとフラグメントの両方でonOptionsItemSelectedを使用します。
フラグメントでsetHasOptionsMenu(true);
onCreate
またはonCreateView
が呼び出されていることを確認する必要があります。
また、フラグメント内にonCreateOptionsMenu
のオーバーライドを実装する必要があります。
別の可能なケースは、各フラグメントの共通アクションに共通IDを使用する場合です。たとえばR.id.action_add
今日、私はそのような状況にありました。各フラグメント(onOptionItemSelected
を使用して動的に置き換えられた)が同じ_R.id.action_add
_を持っていたため、オプションメニュー[追加]を押すと「間違った」DrawerLayout
が呼び出されました。
短い話ですが、そのような状況にある場合は、フラグメントが表示されていることを常に確認してください。
if (!isVisible()) return false;
長い話ですが、onOptionItemSelected
チェーンに注目してください!
_ MainActivity
|
| onOptionItemSelected
+-----------------------
| return false
|
MyCoolFragment1
|
| onOptionItemSelected
+-----------------------
| return false
|
MyCoolFragment2
|
| onOptionItemSelected
+-----------------------
| return true
|
[item selection handled]
_
あなたがあなたのフラグメントを(何かのような)これを追加すると:
_getSupportFragmentManager()
.beginTransaction()
.replace(R.id.content_frame, MyCoolFragment1.newInstance())
.commit()
_
そして、各フラグメントの共通アクション(たとえば、R.id.action_add)に同じIDを定義しました。それぞれにこの行を追加することを忘れないでください:if(!isVisible())return false;
_@Override
public boolean onOptionsItemSelected(MenuItem item) {
if (!isVisible()) return false; // <-- Not visible? skip!
if (item.getItemId() == R.id.action_add) {
//.TODO whatever
return true; //.Handled!
}
return false; //.Skip
}
_
ViewBarrIndicatorをActionBarSherlockと組み合わせて使用していたときに、この問題が発生しました。これは fixed のようでしたが、まだ問題が発生しました。私が見つけた回避策は、フラグメントを手動で呼び出すことでした。
@Override
public boolean onOptionsItemSelected(MenuItem item)
{
Toast.makeText(this, "From activity", Toast.LENGTH_SHORT).show(); // TODO
Fragment currentFragment = mAdapter.getItem(mPager.getCurrentItem());
if (currentFragment != null && currentFragment instanceof SherlockFragment)
{
((SherlockFragment)currentFragment).onOptionsItemSelected(item);
}
return super.onOptionsItemSelected(item);
}
ツールバーが親アクティビティxmlで定義されている場合は、フラグメントでこれを実行してください。
@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
....
Toolbar toolbar = (Toolbar)getActivity().findViewById(R.id.toolbar);
((AppCompatActivity)getActivity()).setSupportActionBar(toolbar);
setHasOptionsMenu(true);
}
そしてもちろん、以下のようにonCreateOptionsMenuをオーバーライドします
@Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
inflater.inflate(R.menu.edit_menu, menu);
super.onCreateOptionsMenu(menu, inflater);
}
これは私のために働いた唯一の解決策です!
Android開発者サイト- link から
注:FragmentクラスのonCreateOptionsMenu()コールバックを介してフラグメントからメニュー項目をインフレートする場合、ユーザーがそれらの項目の1つを選択すると、システムはそのフラグメントのonOptionsItemSelected()を呼び出します。ただし、アクティビティは最初にイベントを処理する機会があるため、フラグメントの同じコールバックを呼び出す前に、システムはまずアクティビティのonOptionsItemSelected()を呼び出します。アクティビティ内のフラグメントにもコールバックを処理する機会があることを確認するには、falseを返すのではなく、常にデフォルトの動作としてスーパークラスに呼び出しを渡します取り扱っていない場合.
したがって、 Marco HC が最も良い答えです。
onCreateOptionsMenu
、onPrepareOptionsMenu
、onOptionsItemSelected
をextends Fragment
。このフラグメントをロードしているActivityクラスでそれをやってみてください
私は同じ問題を抱えていて、私のために働いた解決策は次のとおりです:
OnPrepareOptionMenu()であってもonOptionsItemSelected()、onMenuItemSelected()を削除またはコメント化して、アクティビティのonCreateOptionsMenu()のみに残します。
@Override
public boolean onCreateOptionsMenu(Menu menu){
MenuInflater inflater=getMenuInflater();
inflater.inflate(R.layout.menu, menu);
return true;
}
FragmentクラスのonCreateView()に次のように記述します。
setHasOptionsMenu(true);
Fragmentクラスに次を追加します。
@Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
super.onCreateOptionsMenu(menu,inflater);
}
@Override
public boolean onOptionsItemSelected(MenuItem item){
switch(item.getItemId()){
case R.id.action_insert:
//doing stuff
return true;
}
return false;
}
テスト済みで動作Android 4.4