Mostrar ActionMode sobre la barra de herramientas

87

Estoy tratando de usar el android.view.ActionModecon el nuevo android.support.v7.widget.Toolbar, además del tradicional android.app.ActionBar. Puedo mostrarlo con:

toolbar.startActionMode(callback);

El problema es que ActionModese muestra sobre el ActionBary no sobre el Toolbar. ¿Existe alguna manera de cambiar esto?

Intenté establecer lo siguiente en mi tema, pero no parece cambiar nada:

<item name="windowActionModeOverlay">true</item>
Gaëtan
fuente
1
Creo que ActionMode es parte de ActionBar y no puedes cambiar su posición
SpyZip
Eso es muy malo. Gracias por la respuesta
Gaëtan
1
¿Ha configurado la barra de herramientas como barra de acciones?
Nikola Despotoski
1
Todavía tienes el mismo problema, ¿alguna actualización sobre esto? Tengo la misma situación, una barra de herramientas como la barra de acción clásica y una barra de herramientas debajo, como encabezado y menú de opciones para los contenidos que se muestran a continuación. enfrenta este problema y no puede bajar el modo de acción.
cV2

Respuestas:

82

Dado que está utilizando Toolbar, también asumo que está utilizando AppCompatActivityy ha reemplazado el incorporado ActionBarcon su Toolbaruso personalizadosetSupportActionBar(toolbar);

En primer lugar, asegúrese de importar el espacio de nombres correcto:

import androidx.appcompat.view.ActionMode;
// Or
import android.support.v7.view.ActionMode;

y no

import android.view.ActionMode;

luego usa

_actionMode = startSupportActionMode(this);

y no

_actionMode = startActionMode(this);
Kuffs
fuente
35
Esto más el windowActionModeOverlayentorno funcionó para mí.
Jimeux
4
Actualmente estoy usando AppCompatActivityy agregar windowActionModeOverlay fue suficiente para mí. Traté de usar la importación android.support.v7.view.ActionModepero no funcionó MultiChoiceModeListener, así que terminé usando en su android.view.ActionModelugar. ¿Sabes si hay una versión de soporte de MultiChoiceModeListener? Gracias
Axel
¿Existe una versión de soporte de MultiChoiceModeListener?
galaxigirl
@galaxigirl, no parece que lo haya. Tienes que manejar los eventos de clic en tu adaptador y ver el titular
peterchaula
67

No lo inicie en su actividad, sino en su barra de herramientas. En tu actividad:

Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
toolbar.startActionMode(mActionModeCallback)

y tienes que usar

<item name="windowActionModeOverlay">true</item>

en su tema según lo declarado por Andre.

Franco
fuente
1
Esto funcionó para mí, porque también tenía un requisito especial. En lugar de implementar ActionMode.Callback, quería implementar MultiChoiceModeListener. El problema con el uso del soporte ActionModees que no parece haber una versión de soporte del MultiChoiceModeListener.
jwir3
43

Prueba esto en tu tema:

<item name="windowActionModeOverlay">true</item>
André Restivo
fuente
Como dije en mi pregunta, ya lo intenté sin éxito. ¡Pero gracias!
Gaëtan
Lo siento, no me di cuenta de que ya lo habías probado. ¿Estás seguro de que no funciona? Esto funciona para mi.
André Restivo
Tuve el mismo problema y esto lo soluciona. ¡Gracias!
Marta Rodríguez
2
Intenté con y sin el android:prefijo y lo puse en el tema de mi aplicación. La ActionModesuperposición de ActionBar, pero la quiero sobre mi Toolbar, que está debajo de ActionBar.
Gaëtan
@ Gaëtan ¿Recibiste una respuesta para esto? Tengo el mismo problema y estoy extendiendo Activity y no AppCompatActivity ya que mi aplicación es compatible con API 21 y superior.
SjDev
15

Creo que lo único que la gente no deja en claro es que la línea

<item name="windowActionModeOverlay">true</item>

se coloca en el tema base, es decir, AppTheme y no AppTheme.NoActionBar

<resources>

<!-- Base application theme. -->
<style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">
    <!-- Customize your theme here. -->
    <item name="colorPrimary">@color/colorPrimary</item>
    <item name="colorPrimaryDark">@color/colorPrimaryDark</item>
    <item name="colorAccent">@color/colorAccent</item>
    <item name="windowActionModeOverlay">true</item>
</style>

<style name="transparent" parent="Theme.AppCompat.Light.NoActionBar">
    <item name="android:windowBackground">@android:color/transparent</item>
    <item name="android:windowIsTranslucent">true</item>
</style>


<style name="AppTheme.NoActionBar">
    <item name="windowActionBar">false</item>
    <item name="windowNoTitle">true</item>
</style>

<style name="AppTheme.AppBarOverlay" parent="ThemeOverlay.AppCompat.Dark.ActionBar" />

<style name="AppTheme.PopupOverlay" parent="ThemeOverlay.AppCompat.Light" />

Zurdo
fuente
Este fue el único cambio que necesitaba. ¡Gracias!
PNDA
5

encuentre su AndroidManifest.xml, luego agregue el código a continuación en su aplicación o tema de actividad

<item name="windowActionModeOverlay">true</item>

asi como:

<style name="WorkTimeListTheme" parent="AppTheme.NoActionBar">
        <item name="windowActionModeOverlay">true</item>
        <item name="actionModeBackground">@color/theme_primary</item>
    </style>
zhangjin
fuente
1

Esta es la solución que hice.

En mi método onCreateActionMode de ActionMode.Callback , agrego esto:

StandaloneActionMode standaloneActionMode = (StandaloneActionMode) actionMode;
Field mContextView;
try {
     mContextView = StandaloneActionMode.class.getDeclaredField("mContextView");
     mContextView.setAccessible(true);
     View contextView = (View) mContextView.get(standaloneActionMode);
     MarginLayoutParams params = (MarginLayoutParams) contextView.getLayoutParams();
     params.topMargin = mToolbar.getTop();
  } catch (NoSuchFieldException e) {
            e.printStackTrace();
  } catch (IllegalAccessException e) {
            e.printStackTrace();
  } catch (IllegalArgumentException e) {
            e.printStackTrace();
  }

Esto funciona para mi.

Avery
fuente
1

He intentado todos los métodos anteriores, pero todavía no funciona. Y luego, probé el siguiente método:

    private class ActionModeCallback implements ActionMode.Callback {
    @Override
    public boolean onCreateActionMode(ActionMode actionMode, Menu menu) {
        actionMode.getMenuInflater().inflate(R.menu.note_find_action, menu);
        return true;
    }

    @Override
    public boolean onPrepareActionMode(ActionMode actionMode, Menu menu) {
        ((AppCompatActivity) getActivity()).getSupportActionBar().hide();
        return false;
    }

    @Override
    public boolean onActionItemClicked(ActionMode actionMode, MenuItem menuItem) {
        return false;
    }

    @Override
    public void onDestroyActionMode(ActionMode actionMode) {
        ((AppCompatActivity) getActivity()).getSupportActionBar().show();
    }
}

Aquí, utilicé el modo de acción y el método startSupportActionMode de la biblioteca de soporte. Al mismo tiempo, también he intentado modificar el tema de una actividad determinada. Seguramente no funciona. Entonces, si realmente no tiene una mejor opción, puede probar esta.

Recientemente, descubrí que usé el marco de colores para habilitar múltiples temas de mi aplicación, esto cambiará el tema en el código. Cuando intenté modificar el estilo en este marco, funciona.

Espero que funcione.

Jeff Wong
fuente
Esto es lo único que funcionó para mí. Muchas gracias.
Rachit
0

Si ve el árbol de vista, puede escribir el siguiente código:

 ViewGroup decorView = (ViewGroup) getWindow().getDecorView();
    traverseView(decorView);
 /**
 * traverse find actionmodebar
 * @param root  view
 */
public void traverseView(View root) {
    if (root==null){
        return;
    }
    if (root instanceof ActionBarContextView){
        root.setVisibility(View.GONE);
        return;
    }
    if ((root instanceof ViewGroup)) { // If view is ViewGroup, apply this method on it's child views
        ViewGroup viewGroup = (ViewGroup) root;
        for (int i = 0; i < viewGroup.getChildCount(); ++i) {
            traverseView(viewGroup.getChildAt(i));
        }
    }
}
usuario2416658
fuente
0

Entonces, después de días pasando por este hilo, finalmente lo hice funcionar. Me gustaría resumir lo que hice.

Nota: Esta es la solución que usa a Toolbarpara reemplazar el predeterminado ActionBaren AppCompatActivity.

  1. Agregué esta línea a mi AppTheme: Le dice a Android que desea que su modo de acción se superponga a la barra de herramientas
<item name="windowActionModeOverlay">true</item>
  1. Utilice las importaciones adecuadas:

Tienes que usar estas importaciones para trabajar con AppCompatActivity:

import androidx.appcompat.view.ActionMode;
// or
import android.support.v7.view.ActionMode;
  1. Inicie ActionMode en su actividad así:
actionMode = startSupportActionMode(callback);

Y no así:

actionMode = startActionMode(callback);

Tu actividad crea el ActionMode en la barra de herramientas automáticamente, porque está configurado como supportActionToolbar. El estilo maneja la reproducción como superposición.

Gracias a @Kuffs y @Lefty.

Leon Latsch
fuente