Afficher le mode d'action sur la barre d'outils

87

J'essaye d'utiliser le android.view.ActionModeavec le nouveau android.support.v7.widget.Toolbar, en plus du traditionnel android.app.ActionBar. Je peux l'afficher avec:

toolbar.startActionMode(callback);

Le problème est que le ActionModeest affiché au-dessus du ActionBar, et non au-dessus du Toolbar. Y a-t-il un moyen de changer cela?

J'ai essayé de définir ce qui suit dans mon thème, mais cela ne semble rien changer:

<item name="windowActionModeOverlay">true</item>
Gaëtan
la source
1
Je pense qu'ActionMode fait partie de l'ActionBar et que vous ne pouvez pas changer sa position
SpyZip
C'est dommage. Merci pour la réponse
Gaëtan
1
Avez-vous défini la barre d'outils comme barre d'actions?
Nikola Despotoski
1
avez toujours le même problème, des mises à jour à ce sujet? J'ai eu la même situation, une barre d'outils comme barre d'action classique et une barre d'outils ci-dessous, comme en-tête et menu d'options pour le contenu ci-dessous. face à ce problème et impossible de déplacer le mode action vers le bas.
cV2

Réponses:

82

Puisque vous utilisez le Toolbar, je suppose également que vous utilisez le AppCompatActivityet que vous avez remplacé le intégré ActionBarpar votre Toolbarutilisation personnaliséesetSupportActionBar(toolbar);

Tout d'abord, assurez-vous que vous importez le bon espace de noms:

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

et pas

import android.view.ActionMode;

puis utilisez

_actionMode = startSupportActionMode(this);

et pas

_actionMode = startActionMode(this);
Kuffs
la source
35
Cela plus le windowActionModeOverlaycadre a fonctionné pour moi.
Jimeux
4
J'utilise actuellement AppCompatActivityet l'ajout windowActionModeOverlay me suffisait. J'ai essayé d'utiliser l'importation android.support.v7.view.ActionModemais cela ne fonctionnait pas avec MultiChoiceModeListener, alors j'ai fini par utiliser à la android.view.ActionModeplace. Savez-vous s'il existe une version de support de MultiChoiceModeListener? Merci
Axel
Existe-t-il une version de support de MultiChoiceModeListener?
galaxigirl
@galaxigirl, ça ne semble pas être le cas. Vous devez gérer les événements de clic dans votre adaptateur et afficher le supportr
peterchaula
67

Ne le lancez pas sur votre activité, mais sur votre barre d'outils. Dans votre activité:

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

et vous devez utiliser

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

dans votre thème comme indiqué par André.

Franc
la source
1
Cela a fonctionné pour moi, car j'avais également une exigence particulière. Au lieu de mettre en œuvre ActionMode.Callback, je voulais mettre en œuvre MultiChoiceModeListener. Le problème avec l'utilisation du support ActionModeest qu'il ne semble pas y avoir de version de support du MultiChoiceModeListener.
jwir3
43

Essayez ceci dans votre thème:

<item name="windowActionModeOverlay">true</item>
André Restivo
la source
Comme indiqué dans ma question, j'ai déjà essayé cela sans succès. Mais merci!
Gaëtan
Désolé, je ne savais pas que vous aviez déjà essayé. Êtes-vous sûr que cela ne fonctionne pas? Ça marche pour moi.
André Restivo
J'ai eu le même problème et cela le résout. Merci!
Marta Rodriguez
2
J'ai essayé avec et sans le android:préfixe, et je l'ai mis dans mon thème d'application. Le ActionModesuperpose le ActionBar, mais je le veux sur mon Toolbar, qui est en dessous du ActionBar.
Gaëtan
@ Gaëtan Avez-vous obtenu une réponse à cela? J'ai le même problème et j'étends Activity et non AppCompatActivity, car mon application prend en charge l'API 21 et plus.
SjDev
14

Je pense que la seule chose que les gens ne disent pas clairement, c'est que la ligne

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

est placé dans le thème de base, c'est-à-dire AppTheme et non dans 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" />

Lefty
la source
C'était le seul changement dont j'avais besoin. Merci!
PNDA
5

trouvez votre AndroidManifest.xml, puis ajoutez le code ci-dessous dans votre application ou thème d'activité

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

alors comme:

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

C'est la solution que j'ai faite.

Dans ma méthode onCreateActionMode d' ActionMode.Callback , j'ajoute ceci:

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

Ça marche pour moi.

Avery
la source
1

J'ai essayé toutes les méthodes ci-dessus, mais cela ne fonctionne toujours pas. Et puis, j'ai essayé la méthode ci-dessous:

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

Ici, j'ai utilisé le mode action et la méthode startSupportActionMode de la bibliothèque de support. En même temps, j'ai également essayé de modifier le thème d'une activité donnée. Sûrement, cela ne fonctionne pas. Donc, si vous n'avez vraiment pas de meilleur choix, vous pouvez essayer celui-ci.

Tout récemment, j'ai découvert que j'avais utilisé le cadre coloré pour activer plusieurs thèmes de mon application, cela changerait le thème dans le code. Quand j'ai essayé de modifier le style dans ce cadre, cela fonctionne.

Esperons que ça marche.

Jeff Wong
la source
C'est la seule chose qui a fonctionné pour moi. Merci beaucoup.
Rachit
0

Si vous voyez l'arborescence des vues, vous pourrez écrire le code ci-dessous:

 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));
        }
    }
}
user2416658
la source