Modo de acción contextual en el fragmento – cerrar si no se centra?
I implementó una barra de modo de acción contextual en un fragmento anidado. Este fragmento es parte de un buscapersonas de vista y el paginador de vistas es también un fragmento y parte de un cajón de navegación.
Mi problema: Quiero cerrar la barra de modo de acción contextual si el fragmento no está más enfocado. Por lo tanto, si paseo por el buscapersonas de vista, la barra de modo de acción debe cerrar. Pero si utilizo el método onPause()
del fragmento anidado, el método no se llama directamente. A menudo espera hasta que hice pasar dos o tres veces adelante … He aquí algunas fotos:
- ¿Cómo puedo añadir un fragmento a un ViewPager? AddView bloquea mi aplicación
- GetActivity devolver nulo del fragmento
- Cómo personalizar las pestañas individuales? (Color de fondo cambiante, color del indicador y color de texto)
- Cómo resolver para viewpager: El niño especificado ya tiene un padre. Debe llamar a removeView () en el padre del niño primero
- Android ViewPager enfoca automáticamente WebView
En la segunda imagen se puede ver que la barra de modo de acción todavía está allí. Así que mi pregunta es: ¿En qué método debo llamar a mi método actionModeBar.finish()
, para cerrar directamente la barra de modo de acción si dejo el fragmento?
Tal vez el código del fragmento le ayude:
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(); } } }
- Android añadió el indicador de círculo a viewpager
- Recyclerviews en ViewPager
- Swipe Gesture aplicado al nivel de fragmento junto con ViewPager con su desplazamiento predeterminado desactivado
- Cómo deslizar imágenes en ViewFlipper o ViewPager
- ¿Cómo escribir el método onClick en el viewpager?
- ViewPager omitir las vistas de devolución dejando en blanco
- ViewPager OnItemClickListener
- Deshabilitar ItemTouchHelper para una parte de un visor
ViewPagers mantiene varias páginas activas en cualquier momento (de forma predeterminada, la página anterior y la página después de la página que se muestra actualmente), por lo que onPause () no se llama hasta que elimine dos páginas.
Su mejor ViewPager.OnPageChangeListener
sería usar un ViewPager.OnPageChangeListener
, y mostrar y ocultar el ActionMode en onPageSelected(..)
(es decir, si la página seleccionada no es la que tiene el ActionMode, ocultar el ActionMode). Es probable que tenga que implementar esto en la actividad que aloja su ViewPager.
Esto funcionó para mí:
@Override public void setUserVisibleHint(boolean isVisibleToUser) { if (!isVisibleToUser && this.listView != null) { //HACK this is done in order to finish the contextual action bar int choiceMode = this.listView.getChoiceMode(); this.listView.setChoiceMode(choiceMode); } }
Combiné el código del OP con el override sugerido por el usuario pomber:
-
ActionMode
elActionMode
en un campo de clase cuando se crea el modo de acción. - Configure el campo de nuevo a
null
cuando se destruye el modo de acción. - Anular
setUserVisibleHint
en mi fragmento y llamar aActionMode#finish()
si el fragmento no está visible en el paginador de vista. - También llamo a
ActionMode#finish()
en el métodoonPause()
del fragmento para cerrar el fragmento si el usuario navega por otra parte.
Código:
@Nullable ActionMode mActionMode = null; @Override public void onActivityCreated(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(new AbsListView.MultiChoiceModeListener() { @Override public void onItemCheckedStateChanged(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 } @Override public boolean onCreateActionMode(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; return true; } @Override public boolean onPrepareActionMode(ActionMode mode, Menu menu) { return false; } @Override public boolean onActionItemClicked(ActionMode mode, MenuItem item) { switch (item.getItemId()) { case R.id.action_delete: confirmDelete(getListView().getCheckedItemIds()); return true; case R.id.action_print: print(getListView().getCheckedItemIds()); return true; } return false; } @Override public void onDestroyActionMode(ActionMode mode) { mActionMode = null; } }); } @Override public void onPause() { super.onPause(); if (mActionMode != null) { mActionMode.finish(); } } @Override public void setUserVisibleHint(boolean isVisibleToUser) { super.setUserVisibleHint(isVisibleToUser); if (mActionMode != null && !isVisibleToUser) { mActionMode.finish(); } }
Esto es lo que funcionó para mí –
- Mantenga una referencia estática al modo de acción en MyFragment:
public static ActionMode mActionMode;
@Override public boolean onCreateActionMode(ActionMode mode, Menu menu) { mActionMode = mode; return true; } @Override public void onDestroyActionMode(ActionMode mode) { mActionMode = null; }
- Establecer
ViewPager.OnPageChangeListener
en MyViewPagerActivity.
mViewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() { .... @Override public void onPageScrollStateChanged(int state) { if(MyFragment.mActionMode != null) MyFragment.mActionMode.finish(); } });
- Android.support.v4.app.FragmentManager O ¿android.app.FragmentManager?
- ¿Qué significa este código java de 4 líneas en la aplicación android?