(非推奨)フラグメントonOptionsItemSelectedが呼び出されない


82

編集: この質問は、非推奨のシャーロックアクションバーに関するものでした。代わりにAndroidサポートライブラリを使用する必要があります

表示される共有と呼ばれるアクションバーメニューオプションを追加しましたfragmentが、選択イベントがキャッチされていません

このように追加します

@Override
public void onCreateOptionsMenu (Menu menu, MenuInflater inflater) {
    MenuItem item = menu.add(0, 7,0, R.string.share);
    item.setIcon(R.drawable.social_share).setShowAsAction(MenuItem.SHOW_AS_ACTION_IF_ROOM);
}

両方でそれを捕獲しようとしているfragmentfragment activityのような

@Override
public boolean onOptionsItemSelected(MenuItem item) {

    switch (item.getItemId()) {
        case 7:
            Intent share = new Intent(Intent.ACTION_SEND);
            share.setType("text/plain");
            share.putExtra(Intent.EXTRA_TEXT, "I'm being sent!!");
            startActivity(Intent.createChooser(share, "Share Text"));
            return true;
        default:
            return super.onOptionsItemSelected(item);
    }
}

と私はsetHasOptionsMenu(true);にありonCreate()ます。

回答:


145

同じ問題が私に起こりました:

onMenuItemSelectedイベントがフラグメントで呼び出されませんでした

検索されたグーグルは解決策を見つけることができず、FragmentActivityにonMenuItemSelectedメソッドを追加しても解決されません。

最後に、http://developer.android.com/guide/topics/ui/actionbar.htmlへの参照に従って問題を解決します。

注:フラグメントからメニュー項目を追加した場合、FragmentクラスのonCreateOptionsMenuコールバックを介して、ユーザーがフラグメントの項目の1つを選択すると、システムはそのフラグメントのそれぞれのonOptionsItemSelected()メソッドを呼び出します。ただし、アクティビティは最初にイベントを処理する機会を得るので、システムはフラグメントに対して同じコールバックを呼び出す前に、アクティビティでonOptionsItemSelected()を呼び出します。

つまり、アクティビティのonOptionsItemSelected()にそのメニュー項目ハンドラーがない場合にのみ、フラグメントのonOptionsItemSelected()が呼び出されます。

次のようにコーディングします----- FragmentActivityのR.action.addのハンドラーを削除します):

@Override
public boolean onOptionsItemSelected(MenuItem item) {

    switch (item.getItemId()) {
        case android.R.id.home:
            popBackStack();             
            return true;        
        case R.id.action_search:
            searchAction();
            return true;
        case R.id.action_logout:
            userLogout();
            return true;
        //case R.id.action_add:
            //return true;    
        default:
            return super.onOptionsItemSelected(item);
    }   
}

また、FragmentのR.action.addのハンドラーは次のようになります。

@Override
public boolean onOptionsItemSelected(MenuItem item) {

    Log.d("onOptionsItemSelected","yes");
    switch (item.getItemId()) {
        case R.id.action_add:
            add();
            return true;    
        default:
            return super.onOptionsItemSelected(item);
    }
}

最後に、追加することを忘れないでください

    setHasOptionsMenu(true);

FragmentのonCreateメソッドで


12
私の場合、フラグメントのメニュークリックをインターセプトするために、FragmentActivityのonOptionsItemSelectedとフラグメントのonOptionsItemSelectedで「false」を返す必要があり、目的の動作を実行します。
エジソンサントス

1
setHasOptionsMenu(true);のフラグメント onCreateとパブリックブールonOptionsItemSelected(MenuItemのアイテム){}内の方法は魔法た
モイセス

@Felixqkフラグメントでこのような問題が発生しています。2つのフラグメントがあります。ただし、フラグメント2のOnOptionsSelectedItemは呼び出されません。フラグメント2は、フラグメント1のメニューオプションを示しています。
roon13 2015

@ Roon13super.onCreateOptionsMenuを削除します。フラグメントのonCreateOptionsMenuから。+ setHasOptionsMenu(true); ActivityonOptionsItemSelectedを削除せずに動作しました。
ahmadalibaloch 2016年

129

私も同じ問題を抱えていましたが、それを機能させるための最後のステップを要約して紹介する方が良いと思います。

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

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

  3. アクティビティのonOptionsItemSelected(MenuItem item)メソッド内でfalse、メニュー項目アクションがフラグメントのonOptionsItemSelected(MenuItem item)メソッドに実装されるときに必ず戻るようにしてください。

例:

アクティビティ

@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;
}

6
return falseアクティビティのonOptionItemSelectedキーです。交換するだけreturn super.onOptionItemSelected(item);
ヨンジェ2014

1
完璧に機能しています。マルコに感謝します。
Rajeev Sahu 2014年

2
素晴らしい答え。onCreateOptionsMenu(Menu menu)をonCreateOptionsMenu(Menu menu、MenuInflater inflater)にフラグメント化する場合は、変更する必要があります
Chris Sprague

1
それは素晴らしい解決策です。Thnakx Marco HC
Patel

1
私の友人の素晴らしい解決策!ありがとう!
ハン・トラン

5

人々があなたに与えた解決策は、フラグメントではなく、アクティビティのメニュー項目のコードを実装することであることに気づきました。私の意見では、アクティビティのcosではなく、フラグメントにコードを実装した方が、はるかに組織化されているように見えると思います。これを行うには、次のようにします。

アクティビティ

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

 @Override
    public boolean onOptionsItemSelected(MenuItem item)
    {            
        switch (item.getItemId())
        {
            case R.id.SomeIDInTheMenueOfTheActivity:
            {
               //something();
                break;
            }
            default:
             //do something default and add the code under : 
             return super.onOptionsItemSelected(item);
        }
        return true;
    }

断片

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

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

     @Override
        public boolean onOptionsItemSelected(MenuItem item)
        {
            switch (item.getItemId())
            {           
                case R.id.SomeIDInFragmentMenue:
                {             
                    break;
                }

                default:
                    return super.onOptionsItemSelected(item);
            }

            return true;
        }

ここで、行(および同様のもの): "return super.onOptionsItemSelected(item);" デバッグのコードに従うかのように、メニューイベント関数がアクティビティで最初に呼び出され、アイテムがアクティビティのスイッチのIDと一致しなかった場合は、アクティビティとフラグメントで非常に重要です-ケース、デバッグ行: "super.onOptionsItemSelected(item);" 必要に応じて、フラグメントでonOptionsItemSelected関数を呼び出します。(フラグメントが多数ある場合は、その行も含めるようにしてください。hirarchyの呼び出しは多少複雑になる可能性があります)。


2

actionbarsherlockを使用しています。これは私のために働いた:

1)dummy_menu.xmlメニューを作成します

<?xml version="1.0" encoding="utf-8"?>

<menu xmlns:android="http://schemas.android.com/apk/res/android" android:layout_height="match_parent" android:layout_width="fill_parent" >
<item
      android:title=""
      android:showAsAction="never"
      android:id="@+id/dummyMenu"
        />

2)アクティビティでは、次のようにメニューを膨らませます。

@Override
public boolean onCreateOptionsMenu(com.actionbarsherlock.view.Menu menu) {
    com.actionbarsherlock.view.MenuInflater inflater = getSupportMenuInflater();
   inflater.inflate(R.menu.dummy_menu,menu);
   return super.onCreateOptionsMenu(menu);
}

3)フラグメントonCreateViewでsetHasOptionsMenu(true)を呼び出し、onCreateOptionsMenuとonOptionsItemSelectedをオーバーライドして、このようにdummyMenuも非表示にします(フラグメント内)

    @Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
    inflater.inflate(R.menu.fragment_actions, menu);
    MenuItem item = menu.findItem(R.id.dummyMenu);
    item.setVisible(false);
    super.onCreateOptionsMenu(menu, inflater);
}

それが誰かを助けることを願っています。


2

アクションバーシャーロック用に編集

私は使用しなければなりませんでした

public boolean onMenuItemSelected(int featureId, MenuItem item) {

メニュー項目をキャプチャするためのメインアクティビティで


同じ問題とそれは私にも感謝して修正しました。onOptionItemSelectedが機能しなかった理由を教えてください。
nadeem gc 2014

シャーロックアクションバーがこのメソッドを使用しない原因
user1634451 2014年

onMenuItemSelectedをonOptionItemSelectedを呼び出すように変更して、ABSからappcompatlibに移動するときにコードが機能するようにします
slott

1
@nadeemgcが機能しない理由は、Androidがオプションメニューとコンテキストメニューの2種類のメニューを認識しているためです。Actionbar Sherlockは、のonContextItemSelected代わりに呼び出すコンテキストメニューを使用しますonOptionsItemSelectedonMenuItemSelected良い仕事に見える理由は、正しい方法、単に転送]をクリックします。
Amru E. 2015

@AmruE。今後ともよろしくお願いいたします。
nadeem gc 2015

2

フラグメントでこれを実行して、アクションが正しくリッスンすることを確認するのは非常に簡単です。

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

0

私はこの問題を抱えていました。間違った方法を上書きしていたからです

onOptionsItemSelected(com.actionbarsherlock.view.MenuItem item)は私が使用したものです。

正しいものを使用していることを確認してください!


0

アクティビティメソッドでスーパークラスにチェーンしていません。onCreateOptionsMenu()がsuper.onCreateOptionsMenu(menu)を返し、onOptionsItemSelected()がsuper.onOptionsItemSelected(item)を返すようにしてください(処理しているアイテムを除き、イベントを処理したことを示すためにtrueを返す必要があります)


0

このコードをtoolbar.bringToFront();次に設定するツールバーをアクティビティに追加する必要があります

 public class MainActivity extends AppCompatActivity {
     protected void onCreate(Bundle savedInstanceState) {
        ...

        Toolbar toolbar = findViewById(R.id.toolbar);
        toolbar.setTitle("Yazd");
        setSupportActionBar(toolbar);
        toolbar.bringToFront(); // <<= add here
         ...
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.