Exibir ActionMode na barra de ferramentas


87

Estou tentando usar o android.view.ActionModecom o novo android.support.v7.widget.Toolbar, além do tradicional android.app.ActionBar. Consigo exibi-lo com:

toolbar.startActionMode(callback);

O problema é que o ActionModeé exibido sobre o ActionBare não sobre o Toolbar. Existe uma maneira de mudar isso?

Tentei definir o seguinte no meu tema, mas não parece mudar nada:

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

1
Acho que ActionMode é parte da ActionBar e você não pode mudar sua posição
— SpyZip

Isso é ruim. Obrigado pela resposta
— Gaëtan,

1
Você definiu a barra de ferramentas como barra de ação?
— Nikola Despotoski

1
ainda tem o mesmo problema, alguma atualização sobre isso? Eu tenho a mesma situação, uma barra de ferramentas como a barra de ação clássica, e uma barra de ferramentas abaixo, como cabeçalho e menu de opções para o conteúdo mostrado abaixo. enfrentando este problema e não é capaz de mover o modo de ação para baixo.
— cV2

Respostas:


82

Como você está usando o Toolbar, também presumo que esteja usando o AppCompatActivitye substituiu o integrado ActionBarpor seu personalizado Toolbarusando setSupportActionBar(toolbar);

Em primeiro lugar, certifique-se de que está importando o namespace correto:

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

e não

import android.view.ActionMode;

então use

_actionMode = startSupportActionMode(this);

e não

_actionMode = startActionMode(this);

35
Isso mais a windowActionModeOverlayconfiguração funcionou para mim.
— Jimeux

4
Atualmente estou usando AppCompatActivitye adicionando windowActionModeOverlay foi o suficiente para mim. Tentei usar o import android.support.v7.view.ActionModemas não funcionou MultiChoiceModeListener, então acabei usando android.view.ActionMode. Você sabe se existe uma versão compatível do MultiChoiceModeListener? Obrigado
— Axel

Existe uma versão compatível com MultiChoiceModeListener?
— galaxigirl,

@galaxigirl, não parece que existe. Você tem que lidar com os eventos de clique em seu adaptador e visualizar holderr
— peterchaula

67

Não o inicie na sua atividade, mas na sua barra de ferramentas. Em sua atividade:

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

e você tem que usar

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

em seu tema, conforme afirmado por Andre.


1
Isso funcionou para mim, porque eu também tinha um requisito especial. Em vez de implementar ActionMode.Callback, eu queria implementar MultiChoiceModeListener. O problema de usar o suporte ActionModeé que não parece haver uma versão de suporte do MultiChoiceModeListener.
— jwir3

43

Experimente isso em seu tema:

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

Conforme afirmado na minha pergunta, já tentei fazer isso sem sucesso. Mas obrigado!
— Gaëtan

Desculpe, não sabia que você já havia tentado. Tem certeza que não funciona? Funciona para mim.
— André Restivo

Tive o mesmo problema e isso resolve. Obrigado!
— Marta Rodriguez

2
Tentei com e sem o android:prefixo e coloquei-o no tema do meu aplicativo. As ActionModesobreposições são ActionBar, mas eu quero sobre as minhas Toolbar, que estão abaixo de ActionBar.
— Gaëtan

@Gaëtan Você obteve uma resposta para isso? Estou tendo o mesmo problema e estou estendendo Activity e não AppCompatActivity, pois meu aplicativo suporta API 21 e superior.
— SjDev

14

Acho que a única coisa que as pessoas não estão deixando claro é que a linha

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

é colocado no tema Base, ou seja, AppTheme e não 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" />


Essa foi a única mudança que eu precisava. Obrigado!
— PNDA

5

encontre seu AndroidManifest.xml, em seguida, adicione o código abaixo em seu aplicativo ou tema de atividade

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

assim como:

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

1

Esta é a solução que fiz.

No meu método onCreateActionMode de ActionMode.Callback , adiciono isto:

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

Funciona para mim.


1

Eu tentei todos os métodos acima, mas ainda não funcionou. E então, tentei o método abaixo:

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

Aqui, usei o modo de ação e o método startSupportActionMode da biblioteca de suporte. Ao mesmo tempo, também tentei modificar o tema de determinada atividade. Certamente, não funciona. Então, se você realmente não tem escolha melhor, você pode tentar este.

Recentemente, descobri que usei o quadro Colorido para habilitar vários temas do meu aplicativo, isso mudará o tema no código. Quando tentei modificar o estilo neste framework, ele funcionou.

Espero que funcione.


Esta é a única coisa que funcionou para mim. Muito obrigado.
— Rachit

0

Se você vir a árvore de visualização, poderá escrever o código abaixo:

 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));
        }
    }
}
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.