Meterial Design最佳体验(1): 使用Toolbar, CoordinatorLayout, AppBarLayout等实现精美标题栏

                      Meterial Design最佳体验(1):

使用Toolbar, CoordinatorLayout, AppBarLayout等实现精美标题栏

 

   作者:

  蒋东国

   时间:

  2017年03月10日 星期五        

   应用来源:

   路痴宝v1.2 (三星C9 Pro)

  博客地址:

   http://blog.csdn.net/andrexpert/article/details/61236581                                            

      

       情景再现“Material Design是Google在2014年的I/O大会提出的一套全新的界面设计语言,它包含了视觉、运动、互动效果等特性,其宗旨就是解决Android平台界面风格不统一的问题。虽然Material Design是一套界面设计语言,但为了方便APP开发,Google提供了一个Design Support库,这个库对一些常见的控件和效果进行了封装,使开发工程师在在不了解Material Design的情况下能够将自己的应用Material化。”

       Material Design特有的设计风格和理念,它给人以精致的美观和良好的体验。自Android 5.0推出以后,不仅谷歌将所有的系统APP使用Material Design风格,软件市场上越来越多的APP也Material化,可见Material Design风格将是未来Android APP追求良好体验的必然趋势。为了使我们的APP也能够Material化,Google官方给出了几点建议:

(1)   遵从Material Design设计原则,部署平台高于Android 5.0;

(2)   使用Material主题;

(3)   使用Desugn Support库等Material风格组件,比如RecyclerView、CardView等;

(4)   使用自定义的shadows和animation……等等。

当然,在学习Material Design之前,我们从最新版QQ(v6.6.9)和摩拜单车借用几张图来感受一样Material Design风格所带来的魅力-侧滑菜单、侵入式带可收缩标题栏。

                               

        好了,在了解Material Design是什么东西之后,接下来就应该上干货了。今天主要讲解如何使用Toolbar、AppBarLayout、Coordinater、CollapsingToolbarLayout控件实现一个如摩拜单车样的侵入式带可折叠效果的标题栏,它们分别出自于SDK自带的库appcompat-v7-24.2.1、design-24.2.1。对于Android Studio开发环境来说,我们只需在buid.gradle文件的依赖中添加如下代码:

    compile'com.android.support:appcompat-v7:24.+'
    compile'com.android.support:design:24.2.1'

1.  创建自定义Material主题

     由于新建的Android项目项目会指定一个默认的主题,这个主题是不具备Material效果而且带默认ActionBar。为此,我们需要使用Material提供的不带ActionBar的主题替换默认主题,新的Material主题会给我们带来诸如Activity切换动画,为系统组件渲染指定颜色、添加系统组件操作动画等效果。

(1)   /res/values/style.xml:创建自定义Material风格主题App,它继承于Support-v7库中定义的Material风格theme,具体代码如下:

<resources>
    <!-- application materialdesign theme. -->
    <style name="CustomAppTheme"parent="android:Theme.Material.Light.NoActionBar">
        <!—以下属性定义(颜色调色板)-->
        <item name=" android: colorPrimary">@color/colorPrimary</item>
        <item name="android:colorPrimaryDark">@color/colorPrimaryDark</item>
        <item name="android:colorAccent">@color/colorAccent</item>
        <item name="android:textColorPrimary">@color/textColorPrimary</item>
        <item name="android:windowBackground">@color/windowBackground</item>
        <item name="android:navigationBarColor">@color/navigationBarColor</item>   
</style>
</resources>

       其中,colorPrimary用于指定标题栏背景颜色;colorPrimaryDark属性用于指定状态栏背景颜色;colorAccent指定诸如chexkboxes、text点击效果;textColorPrimary属性用于指定标题栏标题字体颜色;windowBackground属性指定内容区背景颜色;navigationBarColor属性指定导航栏背景颜色….(详见sdk/docs/preview/material/theme.html)。当然,还有很多属性未列举,可以根据自身需求进行深度定制。需要注意的是,Support-v7库提供的系列Material主题必须在minSdkVersion大于5.0 (API21)基础上使用。当然,我们也可以让CustomAppTheme继承于"Theme.AppCompat.Light.NoActionBar",上述定制的颜色风格仍然有效。

(2)   AndroidManifest.xml:使用自定义Material风格主题

<application
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:theme="@style/ CustomAppTheme ">
…….
</application>

2.  自定隐藏式标题栏实现

    看下运行效果:

    

     那么,我们就来详细了解下Toolbar、AppBarLayout、CoordinatorLayout在这里面都扮演了些什么样的角色。

(1)  android.support.v7.widget.Toolbar

Toolbar是android-support-v7库提供的一个具有Material特性的控件,它不仅继承了ActionBar的所有功能,并且与ActionBar只能固定在顶部不同的是,Toolbar可以随便移动,并且可以同其他控件实现一些Material Design效果。简单介绍了Toolbar控件后,接下来就是如何去使用Toolbar作为Activity的标题栏。首先,activity_main.xml文件中添加Toolbar控件:

<FrameLayout
        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.support.v7.widget.Toolbar
       android:id="@+id/main_toolbar"
      android:layout_width="match_parent"
      android:layout_height="?attr/actionBarSize"
      android:background="@color/colorPrimary"
       android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"
      app:popupTheme="@style/ThemeOverlay.AppCompat.Light" />
</ FrameLayout>

       其中,android:layout_height="?attr/actionBarSize"属性指定Toolbar标题栏的高度;android:theme用于指定Toolbar上元素的主题风格,这里使用Dark深色风格目的是与Toolbar主题的Light浅色风格区分开来;app:popupTheme属性用于指定弹出菜单项的主题风格。然后,我们就可以在MainActivity中使用定义的Toolbar,具体代码如下:

Toolbar mToolbar = (Toolbar)findViewById(R.id.main_toolbar);
//设置Activity的标题栏ActionBar为Toolbar
setSupportActionBar(mToolbar);
//使能Home键
ActionBaractionBar = getSupportActionBar();
if(actionBar!= null){
   actionBar.setDisplayHomeAsUpEnabled(true);
   actionBar.setHomeButtonEnabled(true);
}

当然,我们也可以像系统自带的ActionBar样为标题栏添加菜单项,即在res/menu目录下创建menu_toolbar.xml,并使用app:showAsAction属性来指定每个item按钮显示的位置。其中,always表示永远显示在标题栏上;ifRoom表示按钮在空间足够时显示在标题栏上,否则隐藏到菜单栏中;never表示永远隐藏在菜单栏中。具体配置代码如下:

<?xmlversion="1.0" encoding="utf-8"?>
<menu
   xmlns:android="http://schemas.android.com/apk/res/android"
   xmlns:app="http://schemas.android.com/apk/res-auto">
    <itemandroid:id="@+id/menu_personal"
        android:title="个人主页"
       android:icon="@drawable/ic_personal"
       app:showAsAction="always"/>
    <itemandroid:id="@+id/menu_clear"
        android:title="清空"
       android:icon="@drawable/ic_clear"
       app:showAsAction="ifRoom"/>
    <itemandroid:id="@+id/menu_more"
        android:title="更多"
       android:icon="@drawable/ic_more"
        app:showAsAction="never"/>
</menu>

(2)  android.support.design.widget.CoordinatorLayout

      经过步骤(1),我们已经成功地将系统自带的ActionBar替换成Toolbar,但是如果仅仅是做个替换那就太没意义了。既然要实现一个Material化的标题栏,那么就应该尽量使用具有Material特性的控件。非常明显,FramLayout就是“开刀”的对象,我们使用support-design库中的CoordinatorLayout来替换。CoordinatorLayout可以说是一个加强版的FrameLayout,在普通情况下它的功能与FrameLayout一致。由于CoordinatorLayout控件由Design Support库提供,自然具有Material Design风格特性,并且它还能够能够监听其所有子控件的各种事件,然后自动根据当前布局情况作出合理的响应。为了体现CoordinatorLayout的强大,这里使用Support-design库提供的FloatingActionButton、Snackbar控件来进行演示。其中,Snackbar类似于Toast,但是它允许在提示用户的基础上添加一个可交互按钮;FloatingActionButton是一种悬浮按钮,它默认使用CustomAppTheme主题中定义的colorAccent来作为按钮的颜色。

<?xml version="1.0"encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayoutxmlns: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.support.v7.widget.Toolbar
      android:id="@+id/main_toolbar"
       ……/>
   <android.support.design.widget.FloatingActionButton
       android:id="@+id/main_delete_float_btn"
       android:layout_width="wrap_content"
       android:layout_height="wrap_content"
       android:layout_gravity="bottom|end"
       android:layout_marginBottom="13dp"
       android:layout_marginRight="13dp"
        android:scaleType="centerCrop"
       android:src="@drawable/ic_choose"
       app:elevation="10dp" />
</android.support.design.widget.CoordinatorLayout>

       其中,app:elevation="10dp"属性用于设置FloatingActionButton控件高度,高度值越大,投影范围也就越大。我们使当点击悬浮按钮时,弹出一个Snackbar提示,使用CoordinatorLayout前后效果如下图(a)、(b)所示。由图(a)可知,Snackbar提示条将悬浮菜单覆盖住了,这是由于FrameLayout的布局特性所决定的;而对于图(b)可知,当弹出Snackbar时, FloatingActionButton自动向上移动距离布局边缘的同等距离,这是因为CoordinatorLayout能够自动根据当前布局情况对所有子控件作出合理的响应。MainActivity中相关代码:

FloatingActionButton mBtnDeleteData =(FloatingActionButton)
findViewById(R.id.main_delete_float_btn);
mBtnDeleteData.setOnClickListener(newView.OnClickListener() {
   @Override
   public voidonClick(View view) {
      Snackbar.make(view, "删除数据", Snackbar.LENGTH_SHORT).setAction("取消",
      new View.OnClickListener() {
        @Override
        public void onClick(View v) {
 
        }
       }).show();
    }
});

                      

(3) android.support.design.widget.AppBarLayout

      到这里,一个精致Material风格的标题栏看似已经实现了,那么,接下来我们就向Activity的内容区填充数据吧。我们使用RecyclerView和CardView来枚举内部存储器所有视频列表,由于篇幅原因具体实现就在下一篇博文中介绍。从图(a)的效果来看,视频列表完全把标题栏覆盖了,这是由于CoordinatorLayout本身就是FrameLayout的强化版,FrameLayout在不进行明确定位的情况下默认都会摆放在布局的左上角。为了解决这个问题,我们使用Support-design库中提供的AppBarLayout来解决。AppBarLayout实际上是一个垂直方向的LinearLayout,它在内部做了很多滚动时间的封装,并应用了一些Material Design设计理念。使用方法如下:

<android.support.design.widget.CoordinatorLayout
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.support.design.widget.AppBarLayout
       android:layout_width="match_parent"
       android:layout_height="wrap_content">
               <!—Toolbar添加app: layout_scrollFlags -->
       <android.support.v7.widget.Toolbar
            …..
            app:layout_scrollFlags="scroll|snap|enterAlways"
            …../>
</android.support.design.widget.AppBarLayout>
 
       <!—RecyclerView添加app:layout_behavior -->
   <android.support.v7.widget.RecyclerView
       android:id="@+id/main_pic_list"
        android:layout_width="match_parent"
       android:layout_height="match_parent"
       app:layout_behavior="@string/appbar_scrolling_view_behavior"/>
 
   <android.support.design.widget.FloatingActionButton
       android:id="@+id/main_delete_float_btn"
        ….. />
</android.support.design.widget.CoordinatorLayout>

       我们定义一个AppBarLayout,将Toolbar放置在AppBarLayout中,就可以解决Toolbar被RecyclerView遮挡的问题。但是,还不能够使Toolbar跟随RecyclerView滚动而变化。事实上,当为RecyclerView添加app:layout_behavior="@string/appbar_scrolling_view_behavior"属性后,RecyclerView滚动的时候就已经将滚动事件都通知了AppBarLayout,只是我们还没有进行处理而已,这里就需要为Toolbart添加app: layout_scrollFlags属性,该属性用于实现当AppBarLayout接收到RecyclerView的滚动事件后,它内部的子控件如何对这些事件作出相应的反应。其中,scroll表示当RecyclerView向上滚动时,Toolbar会跟着一起向上滚动并隐藏;enterAlways表示当RecyclerView向下滚动时,Toolbar会跟着一起向下滚动并显示;snap表示当Toolbar还没有完全隐藏或者显示时,会根据当前滚动的距离,自动选择是隐藏还是显示。

             

3.     可折叠式标题栏实现

运行效果演示:

使用Toolbar实现的标题栏看上去和传统的ActionBar区别不大,只不过Toolbar可以相应RecyclerView的滚动事件进行隐藏和显示。为了实现可折叠的标题栏,这里使用support-design库提供的CollapsingToolbarLayout控件。CollapsingToolbarLayout是一个作用在Toolbar基础之上的布局,它不仅能够展示一个标题,而且可以让Toolbar效果变得更加的丰富。需要注意的是,CollapsingToolbarLayout是不能单独使用的,它在设计时只能作为AppBarLayout的直接子布局来使用,而AppBarLayout又必须是CoordinatorLayout的子布局。

(1) 可折叠标题栏界面代码

<android.support.design.widget.CoordinatorLayout 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.support.design.widget.AppBarLayout
        android:id="@+id/personal_info_appBar"
        android:layout_width="match_parent"
        android:layout_height="250dp">

        <android.support.design.widget.CollapsingToolbarLayout
            android:id="@+id/personal_info_collapsingbar_layout"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"
            app:contentScrim="@color/colorPrimary"
            app:layout_scrollFlags="scroll|exitUntilCollapsed">

            <ImageView
                android:id="@+id/personal_info_bar_background"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:scaleType="fitXY"
                app:layout_collapseMode="parallax" />

            <android.support.v7.widget.Toolbar
                android:id="@+id/personal_info_toolbar"
                android:layout_width="match_parent"
                android:layout_height="?attr/actionBarSize"
                app:layout_collapseMode="pin" />
        </android.support.design.widget.CollapsingToolbarLayout>
    </android.support.design.widget.AppBarLayout>
</android.support.design.widget.CoordinatorLayout>

       其中,AppBarLayout标签中使用android:layout_height="250dp"用于设定标题栏可扩展的高度;CollapsingToolbarLayout标签中使用app:contentScrim属性用于指定CollapsingToolbarLayout在趋于折叠状态以及之后的背景颜色、app:layout_scrollFlags属性用于指定接收到NestedScrollView传递的滚动事件后作出何种相应,其中,scoll表示CollapsingToolbarLayout会随着NestedScrollView的滚动一起滚动,exitUntilCollapsed表示当CollapsingToolbarLayout随着滚动完成折叠之后就保留在界面上,不再移除屏幕;ImageView标签即为可折叠标签栏的背景图片,Toolbar标签就是折叠以后的标题栏了,它们都使用了同一个属性-app:layout_collapseMode,该属性用于指定当前控件在CollapsingToolbarLayout控件折叠过程中的折叠模式,其中Toolbar指定成pin,表示在折叠的过程中位置始终保持不便,ImageView指定成parallax,表示在折叠的过程中产生一定的错位偏移。

(2) 内容详情界面代码

      内容详情界面最外布局使用了一个NestedScrollView,它是和AppBarLayout平级的并同属于CoordinatorLayout 的子控件。NestedScrollView是ScrollView的扩展,它不仅允许使用滚动的方式来查看屏幕以外的数据,并且还增加了嵌套响应滚动事件的功能。由于CoordinatorLayout 本身已经可以响应滚动事件了,因此我们在它的内部就需要使用NestedScrollView或RecyclerView来生成滚动事件,通过app:layout_behavior属性来指定一个布局行为,这里指定的是appbar来执行响应NestedScrollView产生的滚动事件。

 <android.support.v4.widget.NestedScrollView
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        app:layout_behavior="@string/appbar_scrolling_view_behavior">

       <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content">

            <android.support.v7.widget.CardView
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_marginBottom="15dp"
                android:layout_marginLeft="15dp"
                android:layout_marginRight="15dp"
                android:layout_marginTop="35dp"
                app:cardCornerRadius="4dp">

                <TextView
                    android:id="@+id/personal_info_detail_tv"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:textSize="16sp"
                    android:layout_margin="7dp" />
            </android.support.v7.widget.CardView>
       </LinearLayout>
</android.support.v4.widget.NestedScrollView>

(3) 悬浮按钮

      通过运行效果gif图可知,在标题栏的右下角会有一个悬浮按钮,用于跳转到路痴宝的下载界面。FloatingActionButton也和AppBarLayout、NestedScrollView平级的并同属于CoordinatorLayout 的子控件。FloatingActionButton中使用app:layout_anchor属性指定了一个锚点,我们将锚点设置为AppBarLayout的ID,这样悬浮按钮就会出现在标题栏的区域内;使用app:layout_anchorGravity属性将悬浮按钮定位在标题栏区域的右小角。

<!--悬浮在标题栏的按钮-->
 <android.support.design.widget.FloatingActionButton
      android:id="@+id/personal_info_float_btn"
      android:layout_width="wrap_content"
      android:layout_height="wrap_content"
      android:layout_margin="16dp"
      android:src="@mipmap/download"
      app:layout_anchor="@id/personal_info_appBar"
      app:layout_anchorGravity="bottom|end" />


码字不易,转载请声明出处:http://blog.csdn.net/andrexpert/article/details/61236581


最后的话:“本文对Material Design进行了简单的介绍,并详细阐述了support-v7、support-design库中CoordinatorLayout、AppBarLayout、Toolbar、CollapsingToolbarLayout、
NestedScrollView、FloatingActionButton等Material风格控件的特性和使用方法。由于篇幅不能太长,文中提及的RecyclerView、CardView、视频缩略图的获取等相关和Demo将再“Material Design最佳体验(2):使用RecyclerView、CardView、SwipeRefreshLayout实现下拉刷新列表中给出。"

关于Demo:第三部分Demo-可折叠式标题栏实现Demo





  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值