向主题自带Toolbar添加按钮的问题及崩溃报错咨询
嗨,我来帮你搞定这两个问题:先解决崩溃的坑,再说说怎么给Toolbar加自定义按钮,不用完全重写Toolbar哦~
一、先搞定IllegalStateException崩溃问题
这个报错的核心原因很简单:你的Activity已经被系统默认分配了一个ActionBar,而你又试图通过setSupportActionBar(toolbar)把自定义Toolbar设为ActionBar,这就导致了重复冲突。
有两种靠谱的解决方式:
1. 使用不带ActionBar的主题(推荐)
直接在AndroidManifest.xml里给你的Activity设置一个不带ActionBar的主题,这样系统就不会自动生成ActionBar了:
<activity android:name=".YourNotesActivity" <!-- 用AppCompat的无ActionBar主题,Material3的话换成Theme.Material3.Light.NoActionBar --> android:theme="@style/Theme.AppCompat.Light.NoActionBar" />
设置完这个主题后,再调用setSupportActionBar(toolbar)就不会崩溃了。
2. 先隐藏系统默认ActionBar
如果不想修改主题,也可以在Activity的onCreate方法里先把系统自带的ActionBar藏起来:
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); // 先检查并隐藏系统ActionBar if (getSupportActionBar() != null) { getSupportActionBar().hide(); } setContentView(R.layout.your_notes_layout); Toolbar toolbar = findViewById(R.id.notes_toolbar); setSupportActionBar(toolbar); }
二、给Toolbar添加自定义按钮,不用完全自定义Toolbar
你说主题自带的Toolbar右侧只有三个点的菜单按钮,其实不用完全重写Toolbar就能添加直接显示的按钮,有两种常用方式:
1. 通过菜单文件添加(适合标准的右侧按钮)
在res/menu目录下创建一个菜单文件,比如menu_notes_toolbar.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"> <!-- 这个按钮会直接显示在Toolbar上 --> <item android:id="@+id/action_add_note" android:icon="@drawable/ic_add" android:title="新建笔记" <!-- always表示一直显示,ifRoom表示有空间才显示 --> app:showAsAction="always" /> <!-- 这个会藏在三个点的菜单里 --> <item android:id="@+id/action_settings" android:title="设置" app:showAsAction="never" /> </menu>
然后在Activity里加载这个菜单,并处理点击事件:
@Override public boolean onCreateOptionsMenu(Menu menu) { // 加载菜单文件 getMenuInflater().inflate(R.menu.menu_notes_toolbar, menu); return true; } // 处理菜单/按钮点击 @Override public boolean onOptionsItemSelected(MenuItem item) { int id = item.getItemId(); if (id == R.id.action_add_note) { // 这里写新建笔记的逻辑 Toast.makeText(this, "新建笔记", Toast.LENGTH_SHORT).show(); return true; } else if (id == R.id.action_settings) { // 打开设置页面 return true; } return super.onOptionsItemSelected(item); }
2. 直接在Toolbar布局里添加按钮(适合灵活布局)
如果需要更自由的布局(比如按钮在左侧、中间加自定义标题、多个按钮排列),可以直接在Toolbar的XML布局里添加View:
<androidx.appcompat.widget.Toolbar android:id="@+id/notes_toolbar" android:layout_width="match_parent" android:layout_height="?attr/actionBarSize" android:background="?attr/colorPrimary"> <!-- 左侧返回按钮 --> <ImageButton android:id="@+id/btn_back" android:layout_width="wrap_content" android:layout_height="wrap_content" android:src="@drawable/ic_back" android:background="?attr/selectableItemBackgroundBorderless" /> <!-- 中间自定义标题 --> <TextView android:id="@+id/toolbar_title" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="我的笔记" android:textSize="20sp" android:textColor="@android:color/white" android:layout_gravity="center" /> <!-- 右侧分享按钮 --> <ImageButton android:id="@+id/btn_share" android:layout_width="wrap_content" android:layout_height="wrap_content" android:src="@drawable/ic_share" android:background="?attr/selectableItemBackgroundBorderless" /> </androidx.appcompat.widget.Toolbar>
然后在Activity里给这些按钮设置点击事件即可,这种方式不需要调用setSupportActionBar(除非你还需要ActionBar的其他功能):
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.your_notes_layout); Toolbar toolbar = findViewById(R.id.notes_toolbar); ImageButton btnBack = findViewById(R.id.btn_back); ImageButton btnShare = findViewById(R.id.btn_share); btnBack.setOnClickListener(v -> finish()); btnShare.setOnClickListener(v -> { // 处理分享逻辑 Toast.makeText(this, "分享笔记", Toast.LENGTH_SHORT).show(); }); }
内容的提问来源于stack exchange,提问作者Wes Lange

