Bolic Bolic - 25 days ago 7
Android Question

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 Problem: I want to close the contextual action mode bar if the fragment is no more focused. So, if I swipe through the view pager the action mode bar should close. But if I use the

onPause()
method of the nested fragment, the method is not called directly. Often it waits until i swiped two or three times forward... Here are some pictures:

enter image description here

enter image description here

In the second picture you can see that the action mode bar is still there. So my question is:
In which method should I call my
actionModeBar.finish()
method, to close directly the action mode bar if i leave the fragment?

Maybe the code of the fragment helps you:

public class EditorFragment extends Fragment {

private static final String KEY_POSITION="position";
ListView listView;
private boolean isMultipleList = false;
private ActionMode acMode;
private int counterChecked = 0;

private ActionMode.Callback modeCallBack = new ActionMode.Callback() {

public boolean onPrepareActionMode(ActionMode mode, Menu menu){
return false;
}

public void onDestroyActionMode(ActionMode mode) {
listView.clearChoices();
for (int i = 0; i < listView.getChildCount(); i++)
listView.setItemChecked(i, false);
listView.post(new Runnable() {
@Override
public void run() {
listView.setChoiceMode(ListView.CHOICE_MODE_NONE);
}
});
isMultipleList = false;
counterChecked = 0;
mode = null;
}

public boolean onCreateActionMode(ActionMode mode, Menu menu) {
mode.setTitle("1 Aufgabe");
mode.getMenuInflater().inflate(R.menu.actionmode, menu);
return true;
}

public boolean onActionItemClicked(ActionMode mode, MenuItem item) {
switch (item.getItemId()) {
case R.id.actionmode_delete:
int choiceCount = listView.getCount();
SparseBooleanArray spBoolArray = listView.getCheckedItemPositions();

DBAufgaben db = new DBAufgaben(MainActivity.getMContext());
db.open();

for (int i = 0; i < choiceCount; i++) {
if(spBoolArray.get(i)){
db.deletContact(listView.getItemIdAtPosition(i));
}

}
Cursor cursor = db.getAllRecords();
AdapterEingang adapterE = new AdapterEingang(MainActivity.getMContext(), cursor, 0);
listView.setAdapter(adapterE);
db.close();
mode.finish();
break;
case R.id.actionmode_cancel:
mode.finish();
break;
}
return false;
}
};

//......//

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {

View rootView = null;
int position = getArguments().getInt(KEY_POSITION, -1);

switch(position){
case 0:
rootView = inflater.inflate(R.layout.pager_list, null);
listView = (ListView) rootView.findViewById(R.id.pager_list);

Context context = MainActivity.getMContext();

DBAufgaben db = new DBAufgaben(context);

db.open();
Cursor cursor = db.getAllRecords();
AdapterEingang adapterE = new AdapterEingang(context, cursor, 0);
listView.setAdapter(adapterE);
db.close();

listView.setOnItemLongClickListener(new OnItemLongClickListener(){



@Override
public boolean onItemLongClick(AdapterView<?> adapterView, View view,
int position, long id) {
if(!isMultipleList){
acMode = MainActivity.getInstance().startActionMode(modeCallBack);
listView.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE);
listView.setItemChecked(position, true);
isMultipleList = true;
counterChecked++;
setNewTitle();
} else {
listView.setItemChecked(position, true);
counterChecked++;
setNewTitle();
}

return true;
}

});
listView.setOnItemClickListener(new OnItemClickListener(){

@Override
public void onItemClick(AdapterView<?> adapterView, View view, int position,
long id) {
Log.d(getTag(), "Datensatz: "+String.valueOf(id));
if(isMultipleList){
if(listView.isItemChecked(position)){
listView.setItemChecked(position, true);
counterChecked++;
setNewTitle();
} else {
listView.setItemChecked(position, false);
counterChecked--;
setNewTitle();
}

}

}

});
break;
default:
rootView = inflater.inflate(R.layout.frag_dummy, null);
TextView txt = (TextView) rootView.findViewById(R.id.dummy_txt);
txt.setText(String.valueOf(position));
break;
}



return(rootView);
}
public void setNewTitle(){
if(counterChecked == 1){
acMode.setTitle(counterChecked+" Aufgabe");
} else {
acMode.setTitle(counterChecked+" Aufgaben");
}
}
@Override
public void onPause(){
super.onPause();
if(isMultipleList){
acMode.finish();
}
}
}

Answer Source

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.