替换时片段添加的清除工具栏菜单选项

时间:2017-04-14 02:56:50

标签: android android-fragments android-actionbar android-toolbar android-menu

我设置了3个“顶级”片段,每个片段都使用自己的子片段管理器来提供向下钻取。这些顶级片段通过使用主活动的支持片段管理器进行替换来切换。

其中一个顶级片段有一个子片段,使用setHasOptionsMenu()onCreateOptionsMenu()向工具栏/操作栏添加一个菜单选项,效果很好。

现在我刚注意到的问题是:

添加新的子片段并隐藏带有菜单项的子片段(并将事务添加到顶级片段的backstack)时,菜单项将消失。类似地,当通过撤消事务再次看到片段时,菜单项将返回。这是期望的行为,似乎完全由Fragment框架处理。

但是,如果子片段可见(因此,其菜单项出现在工具栏中)并且我切换顶级片段,则菜单项仍保留在工具栏中

我原本期望清除菜单项,因为不仅它已经转储了它所属的子片段,甚至它的父片段(在顶层片段上)也被完全替换(甚至没有添加到背斜,直接替换)。

我认为只要传入的顶级片段已经恢复,我就可以在活动上调用invalidateOptionsMenu(),但我觉得我只缺少一些可以自动处理的内容,就像在顶部导航时一样级别片段。

3 个答案:

答案 0 :(得分:5)

在创建或重新创建每个片段之后调用onCreateOptionsMenu方法。 您需要做的是在膨胀新菜单xml之前清除菜单。 尝试这样做:

@Override
public void onViewCreated(View view, @Nullable Bundle savedInstanceState){
    super.onViewCreated(view, savedInstanceState);
    setHasOptionsMenu(true);
}

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

答案 1 :(得分:1)

最简单的方法是在片段中创建接口,并使用onAttach / onDetach方法检查片段可见性:

public class QuickSetup1Fragment extends Fragment {
   private CallbackListener onCallbackListener;
   public QuickSetup1Fragment() {}

   @Override
   public View onCreateView(LayoutInflater inflater, ViewGroup container,
                         Bundle savedInstanceState) {
       View view = inflater.inflate(R.layout.fragment_quick_setup1, container, false);
       return view;
   }

   @Override
   public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
      super.onViewCreated(view, savedInstanceState);
   }

   public interface CallbackListener{
      public void onAttach(); //fragment is visible
      public void onDetach(); //fragment is invisible/replace/destroy
   }

   @Override
   public void onAttach(Context context) {
       super.onAttach(context);
       try {
           onCallbackListener = (CallbackListener) context;
           onCallbackListener.onAttach();
       } catch (ClassCastException e) {
           throw new ClassCastException(context.toString()
                + " must implement CallbackListener");
       }
   }

   @Override
   public void onDetach() {
       super.onDetach();
       onCallbackListener.onDetach();
       onCallbackListener = null;
   }
}

在您的活动类

上实现接口方法
public class QuickSetupActivity extends AppCompatActivity implements QuickSetup1Fragment.CallbackListener{

   @Override
   protected void onCreate(Bundle savedInstanceState) {
       super.onCreate(savedInstanceState);
       setContentView(R.layout.activity_image_view);
       Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
       setSupportActionBar(toolbar);
   }

   @Override
   protected void onPostCreate(@Nullable Bundle savedInstanceState) {
       super.onPostCreate(savedInstanceState);
   }

   @OnClick(R.id.backBtn)
   public void back(View v){
       super.onBackPressed();
   }

   @Override
   public void onAttach(){
      //do something with the menu
   }

   @Override
   public void onDetach(){
      //do something with the menu
   }
}

每次更改片段时,都会触发onAttach / onDetach。您可以在此处执行特定任务,例如管理菜单。

答案 2 :(得分:0)

尝试在破坏子片段之前调用的父片段中实现回调!在回调之内的地方oncreateoptions()