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

Toolbar的简介

Toolbar 是 android 5.0   引入的一个新控件,Toolbar出现之前,我们很多时候都是使用ActionBar以及ActionActivity实现顶部导航栏的,因此Toolbar可以理解为是ActionBar的升级版。Toolbar大大扩展了ActionBar,使用更灵活,不像ActionBar那么固定,Toolbar更像是一般的View元素,可以被放置在view树体系的任意位置,可以应用动画,可以跟着scrollView滚动,可以与布局中的其他view交互。

Toolbar的基本使用

1、要想使用Toolbar,首先应该在Gradle的配置脚本里面添加V7兼容包(代码如下,版本是楠妹妹写本文的时候的版本),或者通过Android  Studio的图形化界面的操作方法把V7兼容包依赖进来。

compile ‘com.android.support:appcompat-v7:23.1.1‘

2、在我们需要顶部导航栏的布局文件当中添加Toolbar,并且配置一些常用的属性(使用自定义属性的时候需要注意把命名空间“app”添加到根节点)。

xmlns:app="http://schemas.android.com/apk/res-auto"

这里只列出一些常用的属性,比如最小高度,返回按钮的图标,背景等等。这里需要注意的是,属性值中的“?”表示对Android系统的主题样式进行重用。意思是如果我们改变了主题样式中的colorPrimary属性的话,Toolbar的背景颜色也会随之改变,因此提醒我们去主题样式中进行一些配置。

<android.support.v7.widget.Toolbar         android:id="@+id/toolbar"         android:layout_width="match_parent"         android:layout_height="wrap_content"         android:background="?attr/colorPrimary"         android:minHeight="?actionBarSize"         app:navigationIcon="@mipmap/arrow_left"         app:title="标题"/>

3、在styles.xml文件中进行一些常用的配置。由于我们使用的是

AppCompatActivity,因此必须使用AppCompat的相关主题,笔者这里使用亮色调的没有ActionBar的主题,注意需要在清单文件当中去使用自己定义的主题。为了完全去掉ActionBar,需要把windowActionBar、windowNoTitle以及加上android声明的也写上,确保把系统自带的以及第三方兼容包的ActionBar都彻底去掉。

<style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">     <item name="colorPrimary">@color/red</item>     <item name="colorPrimaryDark">@color/green</item>     <item name="colorAccent">@color/blue</item>     <item name="android:textColorPrimary">@color/white</item>      <item name="android:windowActionBar">false</item>     <item name="android:windowNoTitle">true</item>      <item name="windowActionBar">false</item>     <item name="windowNoTitle">true</item> </style>

4、下面对主题中的几个颜色进行讲解,请参考下面的图片进行理解。

  • colorPrimaryDark是我们手机最顶端的状态栏的背景颜色(改变它需要Android5.0以及以上的手机支持才行)。
  • colorPrimary是指导航栏的颜色。
  • colorAccent是指我们常用控件比如Button等的颜色。
  • textColorPrimary是指我们导航栏中标题的颜色。
  • windowBackground是指我们窗体的默认颜色。
  • navigationBarColor是指Android手机中虚拟按键的背景颜色。

5、代码中对Toolbar进行常见的操作。可以通过ID找到Toolbar之后,可以对导航图标进行点击监听,前提必须是在布局文件或者java代码中添加了导航图标。同理也可以使用菜单,具体看注释,不再赘述。

Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);  //对Toolbar左边的导航图标进行监听 toolbar.setNavigationOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { Toast.makeText(MainActivity.this, "返回", Toast.LENGTH_SHORT).show(); } });
//Toolbar中使用菜单toolbar.inflateMenu(R.menu.menu_main); toolbar.setOnMenuItemClickListener(new Toolbar.OnMenuItemClickListener() {         @Override     public boolean onMenuItemClick(MenuItem item) {                 switch (item.getItemId()) {                         case R.id.action_item1:                 Toast.makeText(MainActivity.this, "菜单1", Toast.LENGTH_SHORT).show();                                     return true;                         case R.id.action_item2:                 Toast.makeText(MainActivity.this, "菜单2", Toast.LENGTH_SHORT).show();                                     return true;                          case R.id.action_item3:                 Toast.makeText(MainActivity.this, "菜单3", Toast.LENGTH_SHORT).show();                                     return true;         }        return false;      } });

6、运行效果图

Toolbar高级使用篇--自定义Toolbar

通过下面的对比可以知道,原生的Toolbar画面太美不忍直视,一般来说要在项目当中使用Toolbar我们都应该去自定义Toolbar。下面开始讨论如何去自定义Toolbar。

下面先让我给出核心的要点:

  • 自定义布局,添加到Toolbar当中
  • 有必要的时候自定义一些属性
  • 自定义Class继承Toolbar,读取自定义属性,对Toolbar的布局显示,内容进行设置,最后需要对外公开一些函数用于设置标题、监听等。下面通过步骤来详细说明。

1、写一个自定义的布局,用来放入自定义Toolbar。

<?xml version="1.0" encoding="utf-8"?>  <RelativeLayout     xmlns:android="http://schemas.android.com/apk/res/android"     android:layout_width="match_parent"     android:layout_height="wrap_content"     >      <RelativeLayout         android:layout_width="match_parent"         android:layout_height="wrap_content"         android:layout_marginLeft="10dp"         android:layout_marginRight="10dp">          <ImageView             android:id="@+id/toolbar_leftButton"             android:layout_width="@dimen/icon_size"             android:layout_height="@dimen/icon_size"             android:layout_alignParentLeft="true"             android:layout_centerVertical="true"             android:src="@mipmap/icon_background"             android:textColor="@color/white"             android:visibility="visible"             />          <ImageView             android:id="@+id/toolbar_rightButton"             android:layout_width="@dimen/icon_size"             android:layout_height="@dimen/icon_size"             android:layout_alignParentRight="true"             android:layout_centerVertical="true"             android:src="@mipmap/icon_background"             android:textColor="@color/white"             android:visibility="visible"             />          <EditText             android:id="@+id/toolbar_searchview"             style="@style/search_view"             android:layout_width="match_parent"             android:layout_height="wrap_content"             android:layout_centerVertical="true"             android:layout_gravity="center"             android:layout_marginLeft="10dp"             android:layout_marginRight="10dp"             android:layout_toLeftOf="@id/toolbar_rightButton"             android:layout_toRightOf="@id/toolbar_leftButton"             android:drawableLeft="@mipmap/icon_search"             android:gravity="center"             android:hint="请输入搜索内容"             android:visibility="gone"             />          <TextView             android:id="@+id/toolbar_title"             android:layout_width="match_parent"             android:layout_height="wrap_content"             android:layout_centerInParent="true"             android:layout_gravity="center"             android:layout_marginLeft="10dp"             android:layout_marginRight="10dp"             android:layout_toLeftOf="@id/toolbar_rightButton"             android:layout_toRightOf="@id/toolbar_leftButton"             android:gravity="center"             android:textColor="@color/white"             android:textSize="20sp"             android:visibility="gone"             />      </RelativeLayout>  </RelativeLayout>

让我们通过下面两张效果图来进行说明吧O(∩_∩)O~~。

由于一般不推荐把宽高意外的属性写在最外面根节点,因此我在最外面的相对布局里面又内嵌了一个相对布局,并且设置了左右的边距(margin)。至于如何布局要根据实际项目而定。楠妹妹这里的需求是,标题和搜索框能够随时切换。因此标题和搜索框是通过项目布局重叠在一起的,需要用到其中一个的时候就把另外一个隐藏掉。另外需要注意的地方就是,左右按钮最好也不要用Toolbar自带的,因为可能会造成布局不对称问题,使得标题(搜索框)不能居中。在按钮不使用的时候,我们并不是通过gone的方法隐藏掉的,而是通过@mipmap/icon_background空白图片来进行占位,保持布局对称。

2、在values文件夹新建attrs.mxl文件,用于存放自定义的一些属性。这些属性都可以通过字面意思读懂,不详细解释了。

<?xml version="1.0" encoding="utf-8"?> <resources>     <declare-styleable name="CNToolbar">         <attr name="showSearchView" format="boolean"/>         <attr name="leftButtonIcon" format="reference"/>         <attr name="rightButtonIcon" format="reference"/>         <attr name="myTitle" format="string"/>     </declare-styleable>  </resources>

3、自定义Class继承Toolbar。代码的主要工作是初始化界面还有监听器,对外公开操作的接口。

初始化界面的时候需要把自定义属性的值通过TintTypedArray读取进来,然后进行一些界面显示方面的设置。

初始化监听器,需要用到接口的回调。具体步骤是公开的声明接口,接口里面有onClick方法;声明该接口的实现,作为Toolbar的私有成员变量;公开setListener方法,把传进来的Listener实现类赋值给这个成员变量;在必须的时候调用成员变量的onClick方法(如在左边的按钮的点击事件中调用)。

公开一些函数,比如设置标题,设置是否显示搜索框、标题等等。

/**  * 自定义的导航栏  */public class CNToolbar extends Toolbar {      private TextView toolbar_title;      private EditText toolbar_searchview;      private ImageView toolbar_leftButton;      private ImageView toolbar_rightButton;      private View mChildView;      private boolean showSearchView;      private Drawable left_button_icon;      private Drawable right_button_icon;      private String title;      public CNToolbar(Context context) {              this(context, null, 0);     }    public CNToolbar(Context context, @Nullable AttributeSet attrs) {                 this(context, attrs, 0);     }    public CNToolbar(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {                 super(context, attrs, defStyleAttr);        //通过代码得到布局文件当中一些属性的值         final TintTypedArray a = TintTypedArray.obtainStyledAttributes(getContext(), attrs,                 R.styleable.CNToolbar, defStyleAttr, 0);         showSearchView = a.getBoolean(R.styleable.CNToolbar_showSearchView, false);         left_button_icon = a.getDrawable(R.styleable.CNToolbar_leftButtonIcon);         right_button_icon = a.getDrawable(R.styleable.CNToolbar_rightButtonIcon);         title = a.getString(R.styleable.CNToolbar_myTitle);         a.recycle();        //初始界面         initView();        //初始监听器         initListener();     }    /**      * 初始化布局      */     private void initView() {                 if (mChildView == null) {             mChildView = View.inflate(getContext(), R.layout.toolbar, null);              toolbar_title = (TextView) mChildView.findViewById(R.id.toolbar_title);             toolbar_searchview = (EditText) mChildView.findViewById(R.id.toolbar_searchview);             toolbar_leftButton = (ImageView) mChildView.findViewById(R.id.toolbar_leftButton);             toolbar_rightButton = (ImageView) mChildView.findViewById(R.id.toolbar_rightButton);                             //添加自定义的布局到Toolbar             addView(mChildView);            //设置标题、搜索框、左右按钮是否显示,并且设置按钮的图标             if (showSearchView) {                 showSearchview();                 hideTitle();             } else {                 hideSearchview();                 showTitle();                                     if (title != null) {                     toolbar_title.setText(title);                 }             }            if (left_button_icon != null) {                 toolbar_leftButton.setImageDrawable(left_button_icon);             }            if (right_button_icon != null) {                 toolbar_rightButton.setImageDrawable(right_button_icon);             }         }      }    /**      * 重写设置标题的方法      *      * @param title      */     @Override     public void setTitle(CharSequence title) {         toolbar_title.setText(title);     }    @Override     public void setTitle(@StringRes int resId) {         toolbar_title.setText(resId);     }    /**      * 设置左右按钮的图标      *      * @param d      */     public void setLeftButtonIconDrawable(Drawable d) {         toolbar_leftButton.setImageDrawable(d);     }    public void setRightButtonIconDrawable(Drawable d) {         toolbar_rightButton.setImageDrawable(d);     }    /**      * 标题与搜索框的切换      */     public void setShowSearchView() {         hideTitle();         showSearchview();     }    public void setShowTitleView(String title) {         hideSearchview();         showTitle();         toolbar_title.setText(title);     }    /**      * 左右按钮的监听      */     private void initListener() {         toolbar_leftButton.setOnClickListener(new OnClickListener() {                         @Override             public void onClick(View v) {                                 if (onLeftButtonClickListener != null) {                     onLeftButtonClickListener.onClick();                 }             }         });          toolbar_rightButton.setOnClickListener(new OnClickListener() {                         @Override             public void onClick(View v) {                                 if (onRightButtonClickListener != null) {                     onRightButtonClickListener.onClick();                 }             }         });     }    public interface OnLeftButtonClickListener {                 void onClick();     }    public interface OnRightButtonClickListener {                 void onClick();      }    private OnLeftButtonClickListener onLeftButtonClickListener;             private OnRightButtonClickListener onRightButtonClickListener;             public void setOnLeftButtonClickListener(OnLeftButtonClickListener listener) {         onLeftButtonClickListener = listener;     }    public void setOnRightButtonClickListener(OnRightButtonClickListener listener) {         onRightButtonClickListener = listener;     }    /**      * 设置标题或者搜索框是否显示      */     private void showTitle() {         toolbar_title.setVisibility(View.VISIBLE);     }    private void hideTitle() {         toolbar_title.setVisibility(View.GONE);     }    private void showSearchview() {         toolbar_searchview.setVisibility(View.VISIBLE);     }    private void hideSearchview() {         toolbar_searchview.setVisibility(View.GONE);     } }          4、使用,在必须的地方如同一般的控件去使用就可以了,注意加上自定义属性的命名空间,一般为auto就可以了。  <?xml version="1.0" encoding="utf-8"?>     <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"               xmlns:app="http://schemas.android.com/apk/res-auto"               android:layout_width="match_parent"               android:layout_height="match_parent"               android:orientation="vertical">      <com.nan.cnshop.widget.CNToolbar         android:id="@+id/toolbar"         android:layout_width="match_parent"         android:layout_height="wrap_content"         android:background="?attr/colorPrimary"         android:minHeight="?actionBarSize"         app:leftButtonIcon="@mipmap/icon_back_32px"         app:showSearchView="false"         app:myTitle="首页"         />      <WebView         android:id="@+id/webview"         android:layout_width="match_parent"         android:layout_height="match_parent"         />        </LinearLayout>

4、使用,在必须的地方如同一般的控件去使用就可以了,注意加上自定义属性的命名空间,一般为auto就可以了。

<?xml version="1.0" encoding="utf-8"?>     <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"               xmlns:app="http://schemas.android.com/apk/res-auto"               android:layout_width="match_parent"               android:layout_height="match_parent"               android:orientation="vertical">      <com.nan.cnshop.widget.CNToolbar         android:id="@+id/toolbar"         android:layout_width="match_parent"         android:layout_height="wrap_content"         android:background="?attr/colorPrimary"         android:minHeight="?actionBarSize"         app:leftButtonIcon="@mipmap/icon_back_32px"         app:showSearchView="false"         app:myTitle="首页"         />      <WebView         android:id="@+id/webview"         android:layout_width="match_parent"         android:layout_height="match_parent"         />        </LinearLayout>

代码当中也可以使用了,具体就不再赘述了。

final CNToolbar toolbar = (CNToolbar) v.findViewById(R.id.toolbar);  toolbar.setOnLeftButtonClickListe
时间: 2024-12-20 07:31:08

Android编程最完整的ToolBar开发指南的相关文章

开发者必看|Android 8.0 新特性及开发指南

背景介绍 谷歌2017 I/O开发者大会今年将于5月17-19日在美国加州举办.大会将跟往年一样发布最新的 Android 系统,今年为 Android 8.0.谷歌在今年3 月21日发布 Android 新系统开发者预览版时已给新系统取名为 Android O.自2008 年发布以来, Android 依靠 Google 的生态运作,全球市场份额在2016年底已超过85% .而近几年依靠 Android 发展起来的智能手机厂商不断增加, Android 生态大家庭也正在不断壮大. Androi

《Android编程权威指南》-读书笔记(十一) 完善CriminalIntent

<Android编程权威指南>-读书笔记(十一) 完善CriminalIntent 在上篇文章中,我们跟随本书作者,使用了单个的Fragment做了最简单的插入操作.本篇文章将跟随作者进行更深入的完善各种功能. 本章目标: 使用ListFragment显示列表 fragment之间传递数据 使用ViewPager来实现划屏显示 对话框 使用ListFragment显示列表 如果是挑战,或者没有UI我会给出草图之类的UI.或手画或Axure原型.每次例子本书都给出了最终UI,所以这步基本都可以省

Android编程权威指南-读书笔记(二)-第一个小程序

Android编程权威指南-读书笔记(二) -第一个小程序 第一个例子介绍 应用名为GeoQuiz.用户通过单击True或False按钮来回答屏幕上的问题,GeoQuiz可即时反馈答案正确与否. 这个例子为我们简单介绍了几个基本组件的使用,以及基本的事件监听.让我们对基本组件的使用和事件的监听有一个基本的了解. 这篇文章分为2个部分,第一部分就是创建简单的UI.第二个部分就是对这个UI增加代码来响应一些操作. (注:所有不明白或者不理解的东西其实都不重要,后面都会有更详细的介绍.) 本章的目标

电子书 Android编程权威指南 第2版.pdf

Big Nerd Ranch是美国一家专业的移动开发技术培训机构.本书主要以其Android训练营教学课程为基础,融合了几位作者多年的心得体会,是一本完全面向实战的Android编程指南.全书共34章,详细介绍了8个Android 应用.通过这些精心设计的应用,读者可掌握很多重要的理论知识和开发技巧,获得前沿的开发经验. 如果你熟悉Java语言,或者了解面向对象编程,那就立刻开始Android编程之旅吧!作者简介Bill PhillipsBig Nerd Ranch骨灰级讲师.他在Big Ner

《Android编程权威指南》PhotoGallery应用梳理

PhotoGalley是<Android编程权威指南>书中另外一个重要的应用.        github:https://github.com/xurui1995/PhotoGallery   (欢迎和谢谢您的star) 在第一个应用CriminalIntent中,主要学习了Intent的使用,Fragment的使用,Sqlite等等. 详情:http://www.cnblogs.com/xurui1995/p/5829458.html 在PhotoGalley的应用中,主要学习Androi

《Android编程权威指南》CriminalIntent项目梳理

相信很多新手或者初级开发人员都已经买了第2版的<Android编程权威指南>, 这本书基于Android Studio开发,对入门人员来说是很好的选择,但是很可惜的是, 在完成一个项目后,缺少对项目的一个大体上的梳理,本书在7-17章花了大量篇幅介 绍CriminalIntent应用,所以这里在完成CriminalIntent之后,我在这里自己对项目进行梳理. 介绍:CriminalIntent应用能记录陋习的标题,日期以及照片,也支持在联系人当中查找当事人,通过E-mail, Twitter

android编程权威指南 第三版 pdf

下载地址:网盘下载 Big Nerd Ranch是美国一家专业的移动开发技术培训机构.本书主要以其Android训练营教学课程为基础,融合了几位作者多年的心得体会,是一本完全面向实战的Android编程权威指南.全书共36章,详细介绍了8个Android应用的开发过程.通过这些精心设计的应用,你可以掌握很多重要的理论知识和开发技巧,获得宝贵的开发经验. 第3版较之前版本增加了对数据绑定等新工具的介绍,同时新增了针对单元测试.辅助功能和MVVM架构等主题的章节.如果你熟悉Java语言,或者了解面向

《Android编程权威指南》-读书笔记(三)Git初探

<Android编程权威指南>-读书笔记(三)Git初探 版本控制-Git 为什么要使用版本控制 什么是版本控制?我为什么要关心它呢?版本控制是一种记录一个或若干文件内容变化,以便将来查阅特定版本修订情况的系统.在本书所展示的例子中,我们仅对保存着软件源代码的文本文件作版本控制管理,但实际上,你可以对任何类型的文件进行版本控制. 如果你是位图形或网页设计师,可能会需要保存某一幅图片或页面布局文件的所有修订版本(这或许是你非常渴望拥有的功能).采用版本控制系统(VCS)是个明智的选择.有了它你就

移动应用安全开发指南(Android)--完结篇(http://www.bubuko.com/infodetail-577312.html)

1.认证和授权 概述 认证是用来证明用户身份合法性的过程,授权是用来证明用户可以合法地做哪些事的过程,这两个过程一般是在服务器端执行的,但也有的APP出于性能提升或用户体验等原因,将其做在客户端完成,由此导致客户端绕过等问题. 安全准则 在客户端做认证和授权是很难保证安全的,所以应该把认证和授权做在服务器端.如果确实有特殊的需求,可以和安全工程师进行沟通做单一case分析. 尽可能避免在设备上存储用户名和密码,可以使用登录认证后获得的token进行鉴权(同时注意控制token的有效期). 详细描