9

アクティビティ内のフラグメントを変更するたびに、フラグメント アクティビティ (abs) のメニュー項目の可視性を変更したいと考えています。フラグメントは SherlockListFragments です。

表示/非表示にしたいメニュー項目は、メニュー作成時に作成したスピナーです。

public boolean onCreateOptionsMenu(Menu menu) {
    // Inflate the menu; this adds items to the action bar if it is present.
    MenuInflater inflater = getSupportMenuInflater();

    IcsSpinner herbSortSpinner = new IcsSpinner(this, null, R.attr.actionDropDownStyle);
    SpinnerAdapter herbSortSpinnerAdapter = ArrayAdapter.createFromResource(this, R.array.herb_sort_elements, android.R.layout.simple_spinner_dropdown_item);
    herbSortSpinner.setAdapter(herbSortSpinnerAdapter);
    herbSortSpinner.setOnItemSelectedListener(this);
    herbSortSpinner.setId(HERB_SPINNER_ID);
    menu.add(R.string.menu_sort).setActionView(herbSortSpinner).setShowAsAction(MenuItem.SHOW_AS_ACTION_IF_ROOM);

    IcsSpinner noteSortSpinner = new IcsSpinner(this,  null, R.attr.actionDropDownStyle);
    SpinnerAdapter noteSortSpinnerAdapter = ArrayAdapter.createFromResource(this, R.array.note_sort_elements, android.R.layout.simple_spinner_dropdown_item);
    noteSortSpinner.setAdapter(noteSortSpinnerAdapter);
    noteSortSpinner.setOnItemSelectedListener(this);
    noteSortSpinner.setId(NOTE_SPINNER_ID);
    menu.add(R.string.menu_sort).setActionView(noteSortSpinner).setVisible(false).setEnabled(false).setShowAsAction(MenuItem.SHOW_AS_ACTION_IF_ROOM);

    inflater.inflate(R.menu.activity_lexicon, menu);
    menuHolder.setMenu(menu);
    return true;
}

フラグメントを切り替えるための私のロジックは次のとおりです。

public boolean onNavigationItemSelected(int position, long itemId) {

    FragmentManager fragmentManager = getSupportFragmentManager();
    FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
    switch(position) {
    case 0:
        List<Herb> herbList = findHerbsByIntent(getHerbLocale());
        HerbListFragment herbListFragment = new HerbListFragment();
        herbListFragment.setListAdapter(new HerbListAdapter(this, getHerbLocale(), herbList));
        fragmentTransaction.replace(R.id.fragment_container, herbListFragment, HERB_LIST_FRAGMENT_TAG);
        //menuHolder.showHerbsSpinner();
        break;
    case 1:
        SymptomListFragment symptomListFragment = new SymptomListFragment();
        symptomListFragment.setListAdapter(new SymptomListAdapter(this, getDefaultSymptomLocale()));
        fragmentTransaction.replace(R.id.fragment_container, symptomListFragment, SYMPTOM_LIST_FRAGMENT_TAG);
        //menuHolder.showHerbsSpinner();
        break;
    case 2:
        NoteRepository noteRepository = new NoteRepository(this);
        List<Note> notes = noteRepository.getNoticables(ReferedType.HERB);
        NoteListFragment noteListFragment = new NoteListFragment();
        noteListFragment.setListAdapter(new NoteListAdapter(this, getHerbLocale(), notes));
        fragmentTransaction.replace(R.id.fragment_container, noteListFragment, NOTE_LIST_FRAGMENT_TAG);
        //menuHolder.showNotesSpinner();
        break;
    case 3:
        FavoriteRepository favoriteRepository = new FavoriteRepository(this);
        Set<Integer> favoriteHerbs = favoriteRepository.getFavorables(ReferedType.HERB);
        List<Herb> favoriteHerbList = herbRepository.getHerbsByIds(favoriteHerbs, getHerbLocale());
        FavoriteHerbListFragment favoriteHerbListFragment = new FavoriteHerbListFragment();
        favoriteHerbListFragment.setListAdapter(new HerbListAdapter(this, getHerbLocale(), favoriteHerbList));
        fragmentTransaction.replace(R.id.fragment_container, favoriteHerbListFragment, HERB_LIST_FRAGMENT_TAG);
        //menuHolder.showHerbsSpinner();
        break;
    }
    fragmentTransaction.commit();

    return true;
}

私の最初のアイデアは、メニュー オブジェクトをホルダー クラスに保持し、フラグメントを切り替えるたびにそこで操作することでした (上記のすべてのステートメントで)。

static class MenuHolder {

    private Menu mMenu;

    void setMenu(Menu menu) {
        mMenu = menu;
    }

    void showNotesSpinner() {
        if (mMenu != null) {
            mMenu.findItem(HERB_SPINNER_ID).setVisible(false).setEnabled(false);
            mMenu.findItem(NOTE_SPINNER_ID).setVisible(true).setEnabled(true);
        }
    }

    void showHerbsSpinner() {
        if (mMenu != null) {
            mMenu.findItem(NOTE_SPINNER_ID).setVisible(false).setEnabled(false);            
            mMenu.findItem(HERB_SPINNER_ID).setVisible(true).setEnabled(true);
        }
    }
}

私の問題は、アクティビティのローカル定数である特定の ID を持つメニュー項目がないことです。ここで NPE を取得します。誰かがそれを修正する方法を知っていますか? フラグメントの切り替え時にメニューを変更するより良い方法はありますか?

よろしく カルステン

4

2 に答える 2

21

フラグメントの切り替え時にメニューを変更するより良い方法はありますか?

多分はい :)。

ドキュメント:

onCreateOptionsMenu(Menu, MenuInflater) および関連メソッドの呼び出しを受け取ることにより、このフラグメントがオプション メニューの設定に参加することを報告します。

  • フラグメント クラスでonPrepareOptionMenuメソッドをオーバーライドします。

画面の標準オプションメニューを表示する準備をします。これは、メニューが表示されるたびに、メニューが表示される直前に呼び出されます。このメソッドを使用して、アイテムを効率的に有効/無効にしたり、コンテンツを動的に変更したりできます。

次に、このメソッドで、ID でメニュー項目を見つけて、次のように表示/非表示、有効/無効にします。

@Override
public void onPrepareOptionsMenu(Menu menu) {    
    menu.findItem(HERB_SPINNER_ID).setVisible(false).setEnabled(false);
}

続きを読む

于 2014-03-21T08:14:45.320 に答える