Kotlin中无法用自定义Toolbar替换ActionBar问题求助
自定义Toolbar报错解决方案
我创建了一个自定义Toolbar并放置在Activity中,但遇到如下错误:
java.lang.IllegalStateException: Activity com.example.citiesdistance.feature.main.MainActivity@3a04806 does not have an ActionBar set via setSupportActionBar()
注意:
当显示默认ActionBar时,自定义Toolbar能正常工作,但会位于默认ActionBar下方。
相关代码
CustomToolbar类
class BaseToolbar(context: Context, attrs: AttributeSet?) : FrameLayout(context, attrs) { private lateinit var binding: ViewToolbarBinding init { if (attrs != null) { binding = ViewToolbarBinding.inflate(LayoutInflater.from(context), this, true) val attr = context.obtainStyledAttributes(attrs, R.styleable.BaseToolbar) val title = attr.getString(R.styleable.BaseToolbar_bs_title) if (!title.isNullOrEmpty()) binding.toolbarTitleTv.text = title attr.recycle() } } }
view_toolbar.xml(自定义Toolbar布局)
<?xml version="1.0" encoding="utf-8"?> <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="56dp" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools"> <ImageView android:id="@+id/backBtn" android:layout_width="32dp" android:layout_height="32dp" android:scaleType="centerInside" android:background="?selectableItemBackgroundBorderless" android:layout_gravity="center_vertical|start" android:layout_marginStart="16dp" app:srcCompat="@drawable/ic_back"/> <TextView android:id="@+id/toolbarTitleTv" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center_vertical|start" android:layout_marginStart="56dp" style="?textAppearanceHeadline6" tools:text="نام صفحه"/> </FrameLayout>
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" style="@style/WidthHeight.All.BothMatchParent" tools:context=".feature.main.MainActivity"> <com.google.android.material.appbar.AppBarLayout android:layout_width="0dp" android:layout_height="wrap_content" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf="parent"> <com.example.view.BaseToolbar android:id="@+id/testToolBar" android:layout_width="match_parent" android:layout_height="?actionBarSize" app:bs_title="Page 1" /> </com.google.android.material.appbar.AppBarLayout> </androidx.constraintlayout.widget.ConstraintLayout>
themes.xml
<resources xmlns:tools="http://schemas.android.com/tools"> <!-- Base application theme. --> <style name="Theme.CitiesDistance" parent="Theme.MaterialComponents.DayNight.NoActionBar"> . . . </style> </resources>
显示效果
默认ActionBar显示效果

隐藏ActionBar显示效果

解决方案
错误核心原因:代码中可能调用了依赖系统ActionBar的API(如getSupportActionBar()),但当前主题为NoActionBar,且未通过setSupportActionBar()将自定义Toolbar设为替代ActionBar。
步骤1:修改自定义Toolbar继承关系
当前BaseToolbar继承自FrameLayout,无法直接作为ActionBar使用,需改为继承androidx.appcompat.widget.Toolbar:
class BaseToolbar(context: Context, attrs: AttributeSet?) : androidx.appcompat.widget.Toolbar(context, attrs) { private lateinit var binding: ViewToolbarBinding init { binding = ViewToolbarBinding.inflate(LayoutInflater.from(context), this, true) if (attrs != null) { val attr = context.obtainStyledAttributes(attrs, R.styleable.BaseToolbar) val title = attr.getString(R.styleable.BaseToolbar_bs_title) if (!title.isNullOrEmpty()) binding.toolbarTitleTv.text = title attr.recycle() } } }
步骤2:在Activity中设置自定义Toolbar为ActionBar
在MainActivity的onCreate方法中添加以下代码:
override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) val toolbar = findViewById<BaseToolbar>(R.id.testToolBar) setSupportActionBar(toolbar) // 隐藏系统默认标题,使用自定义标题 supportActionBar?.setDisplayShowTitleEnabled(false) }
步骤3:确认主题配置
确保themes.xml中的主题保持NoActionBar,避免默认ActionBar显示:
<style name="Theme.CitiesDistance" parent="Theme.MaterialComponents.DayNight.NoActionBar"> <!-- 其他主题配置项 --> </style>
额外优化
如果不需要AppBarLayout的滚动效果,可直接在布局中使用自定义Toolbar,减少层级:
<com.example.view.BaseToolbar android:id="@+id/testToolBar" android:layout_width="match_parent" android:layout_height="?actionBarSize" app:bs_title="Page 1" app:layout_constraintTop_toTopOf="parent" app:layout_constraintStart_toStartOf="parent" app:layout_constraintEnd_toEndOf="parent"/>
内容的提问来源于stack exchange,提问作者Nima Khalili
相关产品推荐
相关产品推荐

