Zeigen Sie den ActionMode über der Symbolleiste an

87

Ich versuche, das android.view.ActionModemit dem Neuen android.support.v7.widget.Toolbarzusätzlich zum Traditionellen zu verwenden android.app.ActionBar. Ich kann es anzeigen mit:

toolbar.startActionMode(callback);

Das Problem ist, dass das ActionModeüber dem ActionBarund nicht über dem angezeigt wird Toolbar. Gibt es eine Möglichkeit, das zu ändern?

Ich habe versucht, Folgendes in mein Thema aufzunehmen, aber es scheint nichts zu ändern:

<item name="windowActionModeOverlay">true</item>
Gaëtan
quelle
1
Ich denke, ActionMode ist Teil der ActionBar und Sie können seine Position nicht ändern
SpyZip
Das ist sehr schade. Vielen Dank für die Antwort
Gaëtan
1
Haben Sie die Symbolleiste als Aktionsleiste festgelegt?
Nikola Despotoski
1
Haben Sie immer noch das gleiche Problem, irgendwelche Updates dazu? Ich habe die gleiche Situation, eine Symbolleiste als klassische Aktionsleiste und eine Symbolleiste unten als Kopfzeile und Optionsmenü für den unten gezeigten Inhalt. mit diesem Problem konfrontiert und nicht in der Lage, den Aktionsmodus nach unten zu verschieben.
cV2

Antworten:

82

Da Sie das verwenden Toolbar, gehe ich auch davon aus, dass Sie das verwenden AppCompatActivityund das eingebaute ActionBardurch Ihr benutzerdefiniertes ToolbarVerwenden ersetzt haben setSupportActionBar(toolbar);

Stellen Sie zunächst sicher, dass Sie den richtigen Namespace importieren:

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

und nicht

import android.view.ActionMode;

dann benutze

_actionMode = startSupportActionMode(this);

und nicht

_actionMode = startActionMode(this);
Kuffs
quelle
35
Dies und die windowActionModeOverlayEinstellung haben bei mir funktioniert.
Jimeux
4
Ich benutze gerade AppCompatActivityund das Hinzufügen windowActionModeOverlay war genug für mich. Ich habe versucht, Import zu verwenden, android.support.v7.view.ActionModeaber es hat nicht funktioniert MultiChoiceModeListener, also habe ich android.view.ActionModestattdessen verwendet. Wissen Sie, ob es eine Support-Version von gibt MultiChoiceModeListener? Danke
Axel
Gibt es eine Support-Version von MultiChoiceModeListener?
Galaxigirl
@galaxigirl, scheint nicht so zu sein. Sie müssen die Klickereignisse in Ihrem Adapter behandeln und Inhaber anzeigen
peterchaula
67

Starten Sie es nicht in Ihrer Aktivität, sondern in Ihrer Symbolleiste. In Ihrer Aktivität:

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

und du musst verwenden

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

in Ihrem Thema wie von Andre angegeben.

Frank
quelle
1
Das hat bei mir funktioniert, weil ich auch eine besondere Anforderung hatte. Anstatt zu implementieren ActionMode.Callback, wollte ich implementieren MultiChoiceModeListener. Das Problem bei der Verwendung des Supports ActionModebesteht darin, dass es anscheinend keine Support-Version von gibt MultiChoiceModeListener.
jwir3
43

Versuchen Sie dies in Ihrem Thema:

<item name="windowActionModeOverlay">true</item>
André Restivo
quelle
Wie in meiner Frage angegeben, habe ich dies bereits ohne Erfolg versucht. Aber danke!
Gaëtan
Entschuldigung, ich wusste nicht, dass du das schon versucht hast. Bist du sicher, dass es nicht funktioniert? Für mich geht das.
André Restivo
Ich hatte das gleiche Problem und das behebt es. Vielen Dank!
Marta Rodriguez
2
Ich habe es mit und ohne android:Präfix versucht und es in mein Anwendungsthema eingefügt . Das ActionModeüberlagert das ActionBar, aber ich will es über meinem Toolbar, das unter dem liegt ActionBar.
Gaëtan
@ Gaëtan Hast du eine Antwort darauf bekommen? Ich habe das gleiche Problem und erweitere Activity und nicht AppCompatActivity, da meine App API 21 und höher unterstützt.
SjNerd
14

Ich denke, das einzige, was die Leute nicht klar machen, ist, dass die Linie

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

wird im Basisthema platziert, dh AppTheme und nicht in der 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
quelle
Dies war die einzige Änderung, die ich brauchte. Vielen Dank!
PNDA
5

Suchen Sie Ihre AndroidManifest.xml und fügen Sie als Nächstes den folgenden Code in Ihre Anwendung oder Ihr Aktivitätsthema ein

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

So wie:

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

Dies ist die Lösung, die ich gemacht habe.

In meiner onCreateActionMode- Methode von ActionMode.Callback füge ich Folgendes hinzu:

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

Für mich geht das.

Avery
quelle
1

Ich habe alle oben genannten Methoden ausprobiert, aber es funktioniert immer noch nicht. Und dann habe ich die folgende Methode ausprobiert:

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

Hier habe ich den Aktionsmodus und die Methode startSupportActionMode der Unterstützungsbibliothek verwendet. Gleichzeitig habe ich auch versucht, das Thema einer bestimmten Aktivität zu ändern. Sicher funktioniert es nicht. Wenn Sie also wirklich keine bessere Wahl haben, können Sie diese probieren.

Erst kürzlich habe ich festgestellt, dass ich den farbenfrohen Rahmen verwendet habe, um mehrere Themen meiner App zu aktivieren. Dadurch wird das Thema im Code geändert. Als ich versuchte, den Stil in diesem Framework zu ändern, funktioniert es.

Hoffe, es funktioniert.

Jeff Wong
quelle
Dies ist das einzige, was für mich funktioniert hat. Vielen Dank.
Rachit
0

Wenn Sie den Ansichtsbaum sehen, können Sie den folgenden Code schreiben:

 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
quelle