在实际开发中,通常会有应用操作栏,如果整个应用有一个统一风格的应用状态栏的话,我们常常会自己对其封装一个公共的组件在各个地方进行引入。不过官方对其提供栏一个公共状态栏的组件,并且拥有其一些常用的属性。以前是ActionBar,现在叫做ToolBar。而且还可以和一些其它的组件进行联动。这些组件在不满足其使用的话还可以进行充分的拓展,拓展方式也很简单。但是由于是遵照Design风格设计的,这种风格国内用的感觉比较少,所以如果想要对其改造的符合具体使用场景的话,还不如自己组装一个公共状态栏。所以感觉大家也就是在处理一些和其它组件的联动的时候会用到ToolBar。
这里我们从最基本代码演示,现在假如我们创建一个项目。那么这个项目是默认是带着ToolsaBar的。效果如下:
默认代码如下:
AndroidManifest.xml
<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.MyApplication">
application>
themes.xml
<resources xmlns:tools="http://schemas.android.com/tools">
<style name="Theme.MyApplication" parent="Theme.MaterialComponents.DayNight.DarkActionBar">
- "colorPrimary"
>@color/purple_500
- "colorPrimaryVariant"
>@color/purple_700
- "colorOnPrimary">@color/white
- "colorSecondary">@color/teal_200
- "colorSecondaryVariant">@color/teal_700
- "colorOnSecondary">@color/black
- "android:statusBarColor" tools:targetApi="l">?attr/colorPrimaryVariant
style>
resources>
MainActivity.kt
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
}
}
activity_tools_bar.xml
<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">
androidx.constraintlayout.widget.ConstraintLayout>
可以看到在不更改themes的前提下(默认主题可以看到是有ActionBar的),继承AppCompatActivity时候,默认就会带一个状态栏。这个状态栏是通过操作ActionBar进行使用的,所以如果是一些简单的UI和操作的话就不用在布局里面定义新的ToolsBar或者ActionBar了,直接使用这个就可以进行操作,如下
supportActionBar?.title = "test"
这里不使用如下代码
actionBar?.title = "test"
是因为actionBar
这个变量属于Activity
类里面,但是这个类需要调用setActionBar(@Nullable Toolbar toolbar)
进行设置,如果没有设置的话,值就是空的。而supportActionBar
是Appcompatctivity
中调用getSupportActionBar()
通过getDelegate().getSupportActionBar();
中的代理设置的,所以可以使用(这里没有细看,有些地方会有疏漏,并不完全对)。
我们在布局里面添加如下代码:
<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=".ToolsBarActivity">
<androidx.appcompat.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@color/black"
android:minHeight="?attr/actionBarSize"
android:paddingEnd="20dp"
app:title="少数的"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:titleTextColor="@android:color/white"/>
androidx.constraintlayout.widget.ConstraintLayout>
可以看到如下效果:
可以看到我们自己的ToolBar和系统的进行重叠了,这里需要修改系统主题将ActionBar隐藏掉,如下所示:
<style name="AppTheme_NoActionBar" parent="Theme.AppCompat.Light.NoActionBar">
style>
也可以在style里面添加以下代码:
<item name="windowActionBar">falseitem>
<item name="windowNoTitle">trueitem>
例如:
<style name="Theme.AppCompat.Light.NoActionBar">
- "windowActionBar"
>false
- "windowNoTitle"
>true
style>
注意:这里不需要设置supportActionBar = toolBar
即可出现效果。
下面是ToolBar的一些常用属性可以供实际开发配置:
属性名称 | 作用 |
---|---|
toolbar:navigationIcon | 设置toolbar左边按钮图片 |
toolbar:titleTextColor | 主标题颜色 |
toolbar:subtitle | 副标题 |
toolbar:subtitleTextColor | 副标题颜色 |
toolbar:menu | 设置右侧折叠菜单 |
有时候ToolBar右侧需要一个菜单选项,那么可以通过toolbar:menu
进行配置,这里需要创建一个菜单,步骤如下:
首先在../app/res/
下面创建menu
文件夹,里面创建menu.xml
。内容如下:
<menu
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<item
android:id="@+id/action_search"
android:title="search"
android:orderInCategory="1"
android:icon="@mipmap/ic_search"
app:showAsAction="always" />
menu>
在item中有两个需要注意的地方
orderInCategory: 表示排列的顺序,数值为int类型,数值越小,越靠近前面,数值一样,按先后顺序排列
showAsAction:显示规则,其规则如下:
showAsAction 值 | 作用 |
---|---|
always | 总是显示在界面上 |
never | 不显示在界面上,只让出现在右边的三个点中 |
ifRoom | 如果有位置才显示,不然就出现在右边的三个点中 |
菜单的点击事件监听如下:
private val toolbar: Toolbar by lazy {
findViewById(R.id.toolbar)
}
toolbar.setOnMenuItemClickListener {
when(it.itemId){
R.id.action_search -> {
Toast.makeText(this,"搜索",Toast.LENGTH_SHORT).show()
}
}
true
}
一般ToolBar都有左上角的返回键,这里对此的监听如下:
toolbar.setNavigationOnClickListener {
finish()
}
需求总是千奇百怪,比如默认的标题在左侧,但是我们想要显示在中间,该如何处理呢,这里就需要进行拓展。示例如下:
<androidx.appcompat.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@color/black"
android:minHeight="?attr/actionBarSize"
android:paddingEnd="20dp"
app:menu="@menu/main_toolbar_menu"
app:navigationIcon="@mipmap/icon_ic_arrow_back"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:titleTextColor="@android:color/white">
<androidx.appcompat.widget.AppCompatTextView
android:id="@+id/center_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="中间标题"
android:textColor="@color/white"
android:layout_gravity="center"/>
androidx.appcompat.widget.Toolbar>
对控件对监听如下:
findViewById<View>(R.id.center_title).setOnClickListener{
Toast.makeText(this,"标题",Toast.LENGTH_SHORT).show()
}