2013-01-18 52 views
9

我想在更改活動中的片段時更改片段活動的菜單項(abs)的可見性。片段是SherlockListFragments。Android:通過更改片段更改菜單項目的可見性

我想顯示/隱藏菜單項是紡紗廠創建於菜單創作:

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。有沒有人有一個想法,我可以解決這個問題?有沒有更好的方法來改變切換片段的菜單?

問候 卡斯滕

+0

昨天幫了我自己。我已經清理了雜亂的代碼(在onCreate中僅對碎片進行實例化)並將菜單項直接存儲到持有者中。現在它像一個魅力。 – modebm

回答

20

有沒有更好的辦法來改變開關片段菜單嗎?

可能是:)。

的DOC:

報告,該片段想參加由填充選項菜單接收對onCreateOptionsMenu(Menu,MenuInflater)和相關方法的調用。

準備顯示屏幕的標準選項菜單。在菜單顯示之前,每當顯示菜單時都會調用它。您可以使用此方法高效地啓用/禁用項目或以其他方式動態修改內容。

然後,在這種方法中,嘗試找到ID的菜單項,並使其可見/ unvisible,啓用/禁用,像這樣:

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

Read More

+3

這個答案值得更多upvotes。然而,在PreferenceFragment中,必要的Override-decleration將是: public void onPrepareOptionsMenu(Menu menu){/*..*/} 不過,您爲我節省了大量工作。謝謝。 :) –

+1

也幫助了我,謝謝,mMenu應該是菜單,它不應該返回任何東西,因爲它是一個空白。 – fizgig

+0

謝謝@fizgig。回答編輯:) –

0

在我的案例,我有2個片段有不同的菜單項。

在我的MainActivity:

FragmentA fragmentA = new FragmentA(); 
fragmentA.setTargetFragment(fragmentA, 0); 
FragmentB fragmentB = new FragmentB(); 
fragmentB.setTargetFragment(fragmentB, 1); 

和FragmentA和FragmentB有:

@Override 
public void onHiddenChanged(boolean hidden) { 
    super.onHiddenChanged(hidden); 
    if(hidden) { 
     getTargetFragment().setMenuVisibility(false); 
    }else{ 
     getTargetFragment().setMenuVisibility(true); 
    } 
} 

這會讓從片段菜單可以看到當B離開。如果它從B返回A可以看到來自A的舊菜單。

參考:here