原来Toolbar还能这么用?Toolbar使用最全解析。网友:终于不用老是自定义标题栏啦

Posted 宾有为

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了原来Toolbar还能这么用?Toolbar使用最全解析。网友:终于不用老是自定义标题栏啦相关的知识,希望对你有一定的参考价值。

一个Toolbar的UI可以做成什么样?做出什么效果?这是我最近在研究的问题。

目录

除带导航栏的Toolbar、带侧滑菜单栏的Toolbar、滚动页面隐藏Toolbar外,用的都是该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">

    <!--  必须用androidx.appcompat.widget.Toolbar,而不是用ToolBar,用ToolBar有些问题无解  -->
    <androidx.appcompat.widget.Toolbar
        android:id="@+id/toolbar"
        android:layout_width="match_parent"
        android:layout_height="?attr/actionBarSize"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        android:background="@color/purple_700"/>

</androidx.constraintlayout.widget.ConstraintLayout>

带导航图标的Toolbar

相关方法描述
setNavigationIcon(Drawable icon)设置导航图标
setNavigationOnClickListener(OnClickListener listener)设置点击导航按钮监听

实现效果:

带标题的Toolbar

相关方法描述
setTitle(String title)设置标题
setTitleTextColor(int color)设置标题文字颜色
setTitleMarginEnd(int margin)以px为单位设置标题结束边距
setTitleMarginStart(int margin)以px为单位设置标题起始边距
setTitleMarginTop(int margin)以px为单位设置标题头部边距
setTitleMarginBottom(int margin)以px为单位设置标题底部边距
setTitleMargin(int start, int top, int end, int bottom)以px为单位设置标题边距
setTitleTextAppearance(Context context, int resId)设置指定TextAppearance资源的文本颜色、大小、样式、提示颜色和突出显示颜色
getTitleMarginEnd()获得以px为单位标题的结束边距
getTitleMarginStart()获得以px为单位标题的起始边距
getTitleMarginTop()获得以px为单位的标题的顶部边距
getTitleMarginBottom()获得以px为单位标题的底部边距

实现效果:

带小标题的Toolbar

相关方法描述
setSubtitle(CharSequence subtitle)设置副标题文本
setSubTitleTextColor(int color)设置副标题文本颜色
setSubTitleTextAppearance(Context context, int resId)设置指定TextAppearance资源的文本颜色、大小、样式、提示颜色和突出显示颜色
getSubtitle()获得副标题文本

实现效果:

带Logo的Toolbar

相关方法描述
setLogo(int resId)设置Logo图标
setLogoDescription(CharSequence description)设置工具栏标志的描述
getLogoDescription()获得工具栏标志的描述
getLogo()返回一个Drawable类型的Logo

实现效果:

带进度条的Toolbar

相关方法描述
setTitle(String title)设置标题
setTitleTextColor(int color)设置标题文字颜色
setNavigationIcon(Drawable icon)设置导航图标
setProgress(int progress)设置进度条当前进度
<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">

    <androidx.appcompat.widget.Toolbar
        android:id="@+id/toolbar"
        android:layout_width="match_parent"
        android:layout_height="?attr/actionBarSize"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        android:background="@color/purple_700"/>

    <ProgressBar
        android:id="@+id/progressBar"
        style="?android:attr/progressBarStyleHorizontal"
        android:layout_width="match_parent"
        android:layout_height="5dp"
        app:layout_constraintTop_toBottomOf="@id/toolbar"
        app:layout_constraintLeft_toLeftOf="@id/toolbar"
        app:layout_constraintRight_toRightOf="parent"/>


</androidx.constraintlayout.widget.ConstraintLayout>

实现效果:

带菜单的Toolbar

相关方法描述
setPopupTheme(int resId)设置菜单弹出时使用的主题
setOverflowIcon(Drawable icon)设置溢出按钮的图标 ,默认是3个小黑点
inflateMenu(int resId)将菜单资源扩充到此工具栏中
setOnMenuItemClickListener(OnMenuItemClickListener listener)点击菜单的监听事件
setMenuCallbacks(MenuPresenter.Callback pcb, MenuBuilder.Callback mcb)设置菜单回调,必须在访问菜单之前调用
getPopupTheme()获取弹出菜单的主题的资源标识符
getOverflowIcon()获取Drawable类型的溢出菜单图标

在Toolbar上建一个菜单,那就得建一个menu的文件夹与xml文件

鼠标右击res文件夹→NewAndroid Resource Directory


在弹出的窗口,Resource type选择menu即可


点击OK后会在res文件夹下生成一个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/share"
        android:title="分享"/>
    <item
        android:id="@+id/save"
        android:title="保存"/>
</menu>

紧接着Toolbar调用inflateMenu方法绑定创建的xml布局即可实现,只是这个时候还没有对这个菜单做个性化,它是默认的3点黑色圆点的效果,使用setOverflowIcon(Drawable icon)方法对其设置图标后,就成了下面的样子。

点击三个小圆点效果:

两个菜单的Toolbar

设置一个Toolbar有多个菜单,不需要修改Java代码,只要在menu文件的对应item下添加app:showAsAction="always"即可,showAsAction有五个参数,分别是:

相关方法描述
never从不在导航栏上显示,一直放在一处菜单列表里面
always总是在导航栏上显示菜单图标
ifRoom如果导航栏右侧有空间,该项就直接显示在导航栏上,不再放入溢出菜单
withText如果能在导航栏上显示,除了显示图标,还要显示该项的文字说明
collapseActionView操作视图要折叠为一个按钮,点击该按钮再展开操作视图,主要用于SearchView

实现效果:

标题居中的Toolbar

标题居中这一样式实现并不是用ToolbarsetTitleGravity方法,当然也没这样的方法给你。实现标题居中,主要还是得靠Toolbar里的子组件:

<TextView
    android:id="@+id/text"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="标题"
    android:textSize="16sp"
    android:textColor="@color/white"
    android:layout_gravity="center"
    android:visibility="invisible"/>

Toolbar里加上TextView,我们提前在布局上将TextView居中于父组件之中,需要将标题居中的时候调用setVisibility方法,放置View.VISIBLE参数即可将标题居中的样式展示出来。

实现效果:


值得注意的是,在设置各种各样的Toolbar子组件时,切互将子组件的宽度设置为match_parent,子组件的宽度过大,会使Toolbar的一些样式被子组件所覆盖。

带搜索框的Toolbar

带搜索框的Toolbar,使用的是SearchView实现。实现的这一效果,特别需要注意,一定要加上setSupportActionBar(Toolbar toolbar)且将它放在Toolbar初始化后的一行。

接着,重写onCreateOptionsMenu(Menu menu)方法,使用Menu的打气筒绑定一个menu,写一个initSearchView(menu: Menu)方法设置SearchView的一些样式

override fun onCreateOptionsMenu(menu: Menu?): Boolean 
   menuInflater.inflate(R.menu.menu_toolbar3,menu)
   initSearchView(menu!!)
   return super.onCreateOptionsMenu(menu)


fun initSearchView(menu: Menu)
   val item = menu.findItem(R.id.search)
   // 获取搜索框对象
   val searchView = item.actionView as SearchView
   searchView.isIconified = true
   // actionView.setIconifiedByDefault(getIntent().getBooleanExtra("collapse",true));
   // 设置是否显示搜索按钮
   searchView.isSubmitButtonEnabled = true
   // 从系统服务获取搜索的管理器
   val systemService = getSystemService(SEARCH_SERVICE) as SearchManager
   // 创建搜索结果页面的组件名称对象
   val componentName = ComponentName(this, BackButtonActivity::class.java)
   // 从结果页面注册的activity结点获取相关搜索信息,即searchable.xml定义的搜索控件
   val searchableInfo = systemService.getSearchableInfo(componentName)
   // 设置搜索框的可搜索信息
   searchView.setSearchableInfo(searchableInfo)
   // 从搜索框中获取名叫search_src_text的自动完成编辑框
   val search_text: SearchAutoComplete = searchView.findViewById(R.id.search_src_text)
   // 设置文本颜色
   search_text.setTextColor(Color.BLACK)
   // 设置自动完成编辑框的提示文本颜色
   search_text.setHintTextColor(Color.BLACK)
   // 设置文本类型
   searchView.inputType = InputType.TYPE_CLASS_TEXT
   // 设置搜索提示文本
   searchView.queryHint = "请输入搜索内容"
   // 为搜索框设置文本变化监听
   searchView.setOnQueryTextListener(object : SearchView.OnQueryTextListener 
       override fun onQueryTextSubmit(query: String): Boolean 
           // 搜索关键词完成输入
           Toast.makeText(this@BackButtonActivity, "最终输入结果:$query", Toast.LENGTH_SHORT).show()
           return false
       

       override fun onQueryTextChange(newText: String): Boolean 
           // 搜索关键词发生变化
           Toast.makeText(this@BackButtonActivity, "关键词发生改变:$newText", Toast.LENGTH_SHORT).show()
           return false
       
   )

哦,对了,这玩意还得在AndroidManifest.xmlapplication节点下加点代码

<activity android:name="使用SearchView的Activity">
    <intent-filter>
        <action android:name="android.intent.action.SEARCH" />
    </intent-filter>

    <meta-data
        android:name="android.app.searchable"
        android:resource="@xml/searchable" />
</activity>

实现效果:


点击搜索按钮效果:


由于SearchView的控件是privateprotected属性,并不能调用相关的取消、确定图标组件,理论上说是无法修改这些icon,使得能修改的样式极其有限,使用范围也大大缩减。

带导航栏的Toolbar

带导航栏的Toolbar效果与Toolbar标题居中同理,皆是在Toolbar组件里面加一个子组件,只是这个子组件加的是TabLayout,这个时候还没能实现TabLayout居中的效果,TabLayout的文本默认是靠左的,需要再嵌套一个布局,将TabLayout放在布局里面,用上android:gravity="center"就可以居中了。

xml代码:

<LinearLayout 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"
    android:orientation="vertical"
    tools:context=".custon.Custon1Activity">

    <androidx.appcompat.widget.Toolbar
        android:id="@+id/toolbar"
        android:layout_width="match_parent"
        android:layout_height="?attr/actionBarSize"
        android:background="@color/purple_700">

        <LinearLayout
            android:id="@+id/linear"
            android:orientation="vertical"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:gravity="center">

            <com.google.android.material.tabs.TabLayout
                android:id="@+id/tabLayout"
                android:layout_width="wrap_content"
                android:layout_height="match_parent"/>

        </LinearLayout>

    </androidx.appcompat.widget.Toolbar>

    <androidx.viewpager.widget.ViewPager
        android:id="@+id/viewpage"
        android:layout_width="match_parent"
        android:layout_height="match_parent"/>

</LinearLayout>

实现效果:

带侧滑菜单栏的Toolbar

第一次做侧滑菜单,参考了几年前的一个例子,用的是动画+监听屏幕滑动+屏幕滑动后的各种操作。那个例子给我的体验就是,真TM复杂,效果还差的离谱,不优化完全用不了呀!

直到DrawerLayout的出现,问题也随之迎刃而解~

带侧滑菜单栏需要以androidx.drawerlayout.widget.DrawerLayout为根布局,DrawerLayout官网给的解释是实现一个材质设计抽屉小部件。
在以DrawerLayout为根Layoutxml文件可以编写两个界面,分别是Toolbar界面与侧滑菜单界面,要想展示侧滑菜单,必须在侧滑界面的第一层加上android:layout_gravity="left"以表示从左边出现。

随后监听Toolbar的点击事件,当用户点击时执行drawer.openDrawer(GravityCompat.START)展示侧滑菜单。

<androidx.drawerlayout.widget.DrawerLayout 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=".custon.Custon2Activity"
    android:id="@+id/drawer">

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical">


        <androidx.appcompat.widget.Toolbar
            android:id="@+id/toolbar"
            android:layout_width="match_parent"
            android:layout_height="?attr/actionBarSize"
            app:layout_constraintLeft_toLeftOf="parent"
            app:layout_constraintRight_toRightOf="parent"
            app:layout_constraintTop_toTopOf="parent"/>

    </LinearLayout>

    <!--  layout_gravity必须设置,值标识侧滑的方向  -->
    <LinearLayout
        android:layout_width="300dp"
        android:layout_height="match_parent"
        android:layout_gravity="left"
        android:orientation="vertical"
        android:background="@android:color/white">

        <TextView
            android:id="@+id/text"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:gravity="center"
            android:text="侧滑菜单"/>

    </LinearLayout>

</androidx.drawerlayout.widget.DrawerLayout>

实现效果:

滚动页面隐藏Toolbar

CoordinatorLayout定位顶级应用程序小部件,如AppBarLayoutFloatingActionButton

布局代码就贴出来了,想说也不懂说啥,全是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=".custon.Custon3Activity">

    <androidx.coordinatorlayout.widget.CoordinatorLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent">

        <com.google.android.material.appbar.AppBarLayout
            android:id="@+id/appbar"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            app:layout_constraintLeft_toLeftOf="parent"
            app:layout_constraintRight_toRightOf="parent"
            app:layout_constraintTop_toTopOf="parent" >

            <androidx.appcompat.widget.Toolbar
                android:id="@+id/toolbar"
                android:layout_width="match_parent"
                android:layout_height="?attr/actionBarSize"
                app:layout_scrollFlags="scroll|enterAlways"
        

以上是关于原来Toolbar还能这么用?Toolbar使用最全解析。网友:终于不用老是自定义标题栏啦的主要内容,如果未能解决你的问题,请参考以下文章

APP开发之UI体验—Toolbar

Android ToolBar使用

Android编程最完整的ToolBar开发指南

android ——Toolbar

最详细的 Android Toolbar 开发实践总结(转)

Android Toolbar样式定制详解