2013-01-18 55 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