0

我有3个'顶级'片段的设置,每个片段使用他们自己的子片段管理器来提供向下导航。通过使用主要活动的支持片段管理器替换这些顶级片段。清除工具栏菜单选项时,它被替换为片段

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

现在我只注意到这个问题是这样的:

当一个新的子片段并用菜单项子片段是隐藏的(并添加到顶级片段的堆栈中的交易),菜单项消失。同样,如果通过撤消事务再次显示片段,菜单项会回来。这是期望的行为,似乎完全由Fragment框架处理。

然而,如果子片段是可见的(因此,它的菜单项存在于工具栏中)并且我切换顶层片段,菜单项仍保留在工具栏中。

我会期望菜单项被清除,因为它所属的子片段不仅被转储,而且甚至它的父片段(在顶层片段上)也被完全替换(甚至不被添加到后台,直接替换掉)。

我想我只需在传入的顶级片段恢复时调用invalidateOptionsMenu()就可以了,但是我觉得我只是缺少一些东西,像自动处理顶级片段。

回答

0

尝试在应该在销毁子片段之前调用的父片段中实现回调!里面那个叫回地方oncreateoptions()

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; 
    } 
} 

和落实你的活动的接口方法class

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都会被触发。您可以在这里执行特定的任务,如管理菜单。

+0

谢谢,我已经有这都是服务从活动本身的堆栈中作为独立backstacks真的只是空的片段我的顶级片段类似的设置。这些片段与许多生命周期事件以及后退按钮等事件相关联。我可以通过这种方式轻松使用'invalidateOptionsMenu()',但我非常好奇,为什么当Fragment刚刚隐藏时,菜单似乎自动在Child Fragment Manager中管理,但不在Activity Frag中。经理当片段被完全替换时。我觉得我错过了一些东西。 – RobertoCuba

0

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); 
}