Contextual Action Mode In Fragment - Close If Not Focused?
i implemented a contextual action mode bar in a nested fragement. This fragment is part of a view pager and the view pager is also a fragment and part of a navigation drawer. My Pr
Solution 1:
ViewPagers keep multiple pages active at any one time (by default, the page before and page after the currently shown page), hence why onPause() is not called until you swipe two pages away.
Your best bet would be to use a ViewPager.OnPageChangeListener
, and show and hide the ActionMode in onPageSelected(..)
(i.e. if the page selected isn't the one with the ActionMode, hide the ActionMode). You'll likely have to implement this in the Activity which hosts your ViewPager.
Solution 2:
Here's what worked for me --
- Hold a static reference to the action mode in MyFragment:
public static ActionMode mActionMode;
@OverridepublicbooleanonCreateActionMode(ActionMode mode, Menu menu) {
mActionMode = mode;
returntrue;
}
@OverridepublicvoidonDestroyActionMode(ActionMode mode) {
mActionMode = null;
}
- Set
ViewPager.OnPageChangeListener
in MyViewPagerActivity.
mViewPager.addOnPageChangeListener(newViewPager.OnPageChangeListener() {
....
@Override
public voidonPageScrollStateChanged(int state) {
if(MyFragment.mActionMode != null) MyFragment.mActionMode.finish();
}
});
Solution 3:
This worked for me:
@OverridepublicvoidsetUserVisibleHint(boolean isVisibleToUser) {
if (!isVisibleToUser && this.listView != null) {
//HACK this is done in order to finish the contextual action barintchoiceMode=this.listView.getChoiceMode();
this.listView.setChoiceMode(choiceMode);
}
}
Solution 4:
I combined code from the OP with the override suggested by user pomber:
- I save the
ActionMode
to a class field when the action mode is created. - I set the field back to
null
when the action mode is destroyed. - I override
setUserVisibleHint
in my fragment and callActionMode#finish()
if the fragment isn't visible in the view pager. - I also call
ActionMode#finish()
in theonPause()
method of the fragment to close the fragment if the user navigates elsewhere.
Code:
@NullableActionMode mActionMode = null;
@OverridepublicvoidonActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
// Start out with a progress indicator.setListShownNoAnimation(false);
setEmptyText(getText(R.string.no_forms_in_progress));
getListView().setChoiceMode(AbsListView.CHOICE_MODE_MULTIPLE_MODAL);
getListView().setMultiChoiceModeListener(newAbsListView.MultiChoiceModeListener() {
@OverridepublicvoidonItemCheckedStateChanged(ActionMode mode, int position, long id, boolean checked) {
// Here you can do something when items are selected/de-selected,// such as update the title in the CAB
}
@OverridepublicbooleanonCreateActionMode(ActionMode mode, Menu menu) {
MenuInflater inflater = mode.getMenuInflater();
inflater.inflate(R.menu.context_saved_item, menu);
inflater.inflate(R.menu.context_instance_list, menu);
mActionMode = mode;
returntrue;
}
@OverridepublicbooleanonPrepareActionMode(ActionMode mode, Menu menu) {
returnfalse;
}
@OverridepublicbooleanonActionItemClicked(ActionMode mode, MenuItem item) {
switch (item.getItemId()) {
case R.id.action_delete:
confirmDelete(getListView().getCheckedItemIds());
returntrue;
case R.id.action_print:
print(getListView().getCheckedItemIds());
returntrue;
}
returnfalse;
}
@OverridepublicvoidonDestroyActionMode(ActionMode mode) {
mActionMode = null;
}
});
}
@OverridepublicvoidonPause() {
super.onPause();
if (mActionMode != null) {
mActionMode.finish();
}
}
@OverridepublicvoidsetUserVisibleHint(boolean isVisibleToUser) {
super.setUserVisibleHint(isVisibleToUser);
if (mActionMode != null && !isVisibleToUser) {
mActionMode.finish();
}
}
Solution 5:
You can use the onDestroyOptionsMenu()
method inside your Fragment:
publicvoidonDestroyOptionsMenu() {
super.onDestroyOptionsMenu();
if (mActionMode != null) {
mActionMode.finish();
mActionMode = null;
}
}
Post a Comment for "Contextual Action Mode In Fragment - Close If Not Focused?"