web-dev-qa-db-ja.com

(非推奨)フラグメントonOptionsItemSelectedが呼び出されていません

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

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

このように追加しています

@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()があります。

80
user1634451

アクションバーのシャーロック使用のために編集

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

public boolean onMenuItemSelected(int featureId, MenuItem item) {

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

2
user1634451

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

onMenuItemSelectedイベントがFragmentで呼び出されませんでした

検索したグーグルは解決策を見つけることができず、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);
    }   
}

そして、フラグメントの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メソッドで

145
Felixqk

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

  1. フラグメントのsetHasOptionsMenu(true)メソッドにonCreate(Bundle savedInstanceState)メソッドを追加します。

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

  3. アクティビティの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, 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;
}
127
Marco HC

人々があなたに与えた解決策は、フラグメントではなくアクティビティのメニュー項目のコードを実装することであることに気づきました。あなたがフラグメントのコードを実装した場合、アクティビティの方が良いと思うので、もっと洗練されたものになると思います。これを行うには、次のようにします。

アクティビティ

@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と一致しなかった場合、ケース、degault行: "super.onOptionsItemSelected(item);"必要に応じて、フラグメントでonOptionsItemSelected関数を呼び出します。 (多くのフラグメントがある場合は、呼び出しの階層が多少複雑になる可能性があるため、その行も必ず含めてください)。

5
Malfonde

あなたのアクションが正しくリッスンすることを確認するためにあなたのフラグメントでそれを行うことができるとても簡単です:

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

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
okkko

この問題がありました。間違った方法をオーバーライドしていたからです

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

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

0
Barrie Galitzky

このコードを追加する必要があります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
         ...
0
Mahdi Afkhami

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

0