You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Android API31下Toolbar异常:长按按钮出现空白白栏而非切换图标

问题描述

基于API 31开发一款带有Toolbar的应用,布局中有一个绿色按钮,预期长按该按钮时,Toolbar的搜索图标会切换为删除和编辑图标。但实际操作后,原本的紫色Toolbar未发生变化,其上方却出现了一个空白的白栏。

操作前后效果

  • 长按前:操作前截图
  • 长按后:操作后截图

相关代码

MainActivity.java

public class MainActivity extends AppCompatActivity {
    private ActionMode mActionMode;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        Toolbar toolbar = (Toolbar) findViewById(R.id.mainMenuToolbar);
        setSupportActionBar(toolbar);

        Button myButton = findViewById(R.id.mybutton);
        myButton.setText("  main menu  ");
        myButton.setOnLongClickListener(new View.OnLongClickListener() {
            @Override
            public boolean onLongClick(View v) {
                if (mActionMode != null) {
                    return false;
                }
                myButton.setText(" context menu  ");
                mActionMode = startSupportActionMode(mActionModeCallback);
                return true;
            }
        });
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.menu_main, menu);
        return true;
    }

    private ActionMode.Callback mActionModeCallback = new ActionMode.Callback() {
        @Override
        public boolean onCreateActionMode(ActionMode mode, Menu menu) {
            mode.getMenuInflater().inflate(R.menu.context_action_menu, menu);
            return true;
        }
        @Override
        public boolean onPrepareActionMode(ActionMode mode, Menu menu) {
            return false;
        }
        @Override
        public boolean onActionItemClicked(ActionMode mode, MenuItem item) {
            return false;
        }

        @Override
        public void onDestroyActionMode(ActionMode mode) {
            mActionMode = null;
        }
    };
}

activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <com.google.android.material.appbar.AppBarLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:theme="@style/ThemeOverlay.AppCompat.ActionBar"
        app:layout_constraintTop_toTopOf="parent"
        >

        <androidx.appcompat.widget.Toolbar
            android:id="@+id/mainMenuToolbar"
            android:layout_width="match_parent"
            android:layout_height="?attr/actionBarSize"
            android:background="@color/colorPrimary"
            app:title="@string/app_name"
            app:titleTextColor="@color/colorWhite"
            app:popupTheme="@style/Theme.Notes.PopupOverlay" />

    </com.google.android.material.appbar.AppBarLayout>
    
    <TextView
        android:id="@+id/bstext"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Hello World!"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        />

    <Button
        android:id="@+id/mybutton"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Button"
        android:background="@color/colorLightGreen"
        tools:layout_editor_absoluteX="158dp"
        tools:layout_editor_absoluteY="494dp"
        app:layout_constraintBottom_toBottomOf="@id/bstext"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        />
</androidx.constraintlayout.widget.ConstraintLayout>
<menu xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    tools:context="com.example.notes.MainActivity">

    <item
        android:id="@+id/search_stuff"
        android:orderInCategory="100"
        android:icon="@drawable/ic_search_24dp"
        android:title="Search"
        app:showAsAction="always"
        />
</menu>

context_action_menu.xml

<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto">

    <item
        android:id="@+id/delete"
        android:orderInCategory="100"
        android:title="Option 1"
        android:icon="@drawable/ic_delete"
        app:showAsAction="always"
        />
    <item
        android:id="@+id/edit"
        android:orderInCategory="100"
        android:title="Option 2"
        android:icon="@drawable/ic_edit"
        app:showAsAction="always"
        />

</menu>

AndroidManifest.xml

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.testtoolbarapp">

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/Theme.MyToolBar">

        <activity
            android:name=".MainActivity"
            android:exported="true"
            android:label="@string/app_name"
            android:theme="@style/Theme.AppCompat.Light.NoActionBar"
            >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>
</manifest>

解决方案

问题根源

调用startSupportActionMode()会创建一个独立于现有Toolbar的系统级ActionBar,导致出现额外白栏,而非替换原有Toolbar的内容。

修复步骤

  1. 绑定ActionMode到现有Toolbar
    修改MainActivity中长按按钮的逻辑,将startSupportActionMode()替换为toolbar.startActionMode(),让ActionMode直接复用当前Toolbar:

    myButton.setOnLongClickListener(new View.OnLongClickListener() {
        @Override
        public boolean onLongClick(View v) {
            if (mActionMode != null) {
                return false;
            }
            myButton.setText(" context menu  ");
            // 替换原有方法,绑定到当前Toolbar
            mActionMode = toolbar.startActionMode(mActionModeCallback);
            return true;
        }
    });
    
  2. 统一ActionMode样式
    为了让ActionMode的外观和原有Toolbar一致,在res/values/styles.xml中添加ActionMode的样式配置:

    <style name="ActionModeStyle" parent="@style/Widget.AppCompat.ActionMode">
        <item name="background">@color/colorPrimary</item>
        <item name="titleTextColor">@color/colorWhite</item>
    </style>
    

    然后在Activity的主题中引用该样式:

    <style name="Theme.AppCompat.Light.NoActionBar" parent="Theme.AppCompat.Light.NoActionBar">
        <item name="actionModeStyle">@style/ActionModeStyle</item>
    </style>
    
  3. 恢复Toolbar原有状态
    在onDestroyActionMode回调中,恢复按钮文本并确保Toolbar显示原有菜单:

    @Override
    public void onDestroyActionMode(ActionMode mode) {
        mActionMode = null;
        myButton.setText("  main menu  ");
        // 重新加载主菜单
        invalidateOptionsMenu();
    }
    

这样修改后,长按按钮时原有Toolbar会直接替换为删除和编辑图标,不会出现额外白栏,退出ActionMode后也能恢复初始状态。

内容的提问来源于stack exchange,提问作者driftwood

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.13 15:10:28