Android:Material Design(七) 兼容性

导读:

这个兼容库很容易和之前的 Android Support Library 22.1混淆,都是兼容库,区别是这个库多了个Design。 Android Support Library 22.1只是支持了一些基本控件的材料设计化,但是这个库更多的是对一些特效的实现,这个库和github上的很多开源项目是有很大关系的,material design的很多效果,同一种效果在github上有太多的实现,现在官方把部分效果标准化了。最重要的是,Android Design Support Library的兼容性更广,直接可以向下兼容到Android 2.2。

Android Design Support Library

安卓5.0是是有有史以来最重要的安卓版本之一,这其中有很大部分要归功于material design的引入,这种新的设计语言让整个安卓的用户体验焕然一新。我们的详细专题是帮助你开始采用material design的好去处。但是我们也知道,这种设计对于开发者,尤其是那些在意向后兼容的开发者来说是一种挑战。

在Android Design Support Library的帮助下,我们为所有的开发者,所有2.1以上的设备,带来了一些重要的material design控件。你可以在这里面找到navigation drawer view,输入控件的悬浮标签,悬浮操作按钮,snackbar,选项卡以及将这些控件结合在一起的手势滚动框架。
Design Support Library包含8个控件,具体如下:
Widget Name Description

  • android.support.design.widget.TextInputLayout 强大带提示的MD风格的EditText
  • android.support.design.widget.FloatingActionButton MD风格的圆形按钮,来自于ImageView
  • android.support.design.widget.Snackbar 类似Toast,添加了简单的单个Action
  • android.support.design.widget.TabLayout 选项卡
  • android.support.design.widget.NavigationView DrawerLayout的SlideMenu
  • android.support.design.widget.CoordinatorLayout 超级FrameLayout
  • android.support.design.widget.AppBarLayout MD风格的滑动Layout
  • android.support.design.widget.CollapsingToolbarLayout 可折叠MD风格ToolbarLayout

可以到优酷观看视频

导入兼容包

使用Support Library非常简单:
添加引用即可:

compile 'com.android.support:design:22.2.0'

下面我们来看看这些新控件的基本使用方法,我们从最简单的控件开始说起。

抽屉导航是app识别度与内部导航的关键,保持这里设计上的一致性对app的可用性至关重要,尤其是对于第一次使用的用户。 NavigationView 通过提供抽屉导航所需的框架让实现更简单,同时它还能够直接通过菜单资源文件直接生成导航元素。

XML布局

把NavigationView作为DrawerLayout的内容视图来使用,比如下面的布局:

<android.support.v4.widget.DrawerLayout  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:fitsSystemWindows="true">    <!-- your content layout -->    <include layout="@layout/navigation_content"/>    <android.support.design.widget.NavigationView  android:layout_width="wrap_content" android:layout_height="match_parent" android:layout_gravity="start" app:headerLayout="@layout/drawer_header" app:menu="@menu/drawer"/></android.support.v4.widget.DrawerLayout>

你会注意到NavigationView的两个属性:

  • app:headerLayout - 控制头部的布局
  • app:menu - 导航菜单的资源文件(也可以在运行时配置)

app:headerLayout头布局

<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="200dp" android:background="?attr/colorPrimaryDark" android:gravity="center" android:orientation="vertical" android:padding="16dp" android:theme="@style/ThemeOverlay.AppCompat.Dark">    <ImageView  android:layout_width="100dp" android:layout_height="100dp" android:layout_marginTop="16dp" android:background="@drawable/ic_user"/>    <TextView  android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginTop="16dp" android:gravity="center" android:text="XuYisheng" android:textAppearance="@style/TextAppearance.AppCompat.Body1" android:textSize="20sp"/></LinearLayout>

app:menu导航布局

被点击过的item会高亮显示在抽屉菜单中,让用户知道当前是哪个菜单被选中

<?xml version="1.0" encoding="utf-8"?><menu xmlns:android="http://schemas.android.com/apk/res/android">    <group android:checkableBehavior="single">        <item  android:id="@+id/nav_home" android:icon="@drawable/ic_dashboard" android:title="CC Talk"/>        <item  android:id="@+id/nav_messages" android:icon="@drawable/ic_event" android:title="HJ Class"/>        <item  android:id="@+id/nav_friends" android:icon="@drawable/ic_headset" android:title="Words"/>        <item  android:id="@+id/nav_discussion" android:icon="@drawable/ic_forum" android:title="Big HJ"/>    </group>    <item android:title="Version">        <menu>            <item  android:icon="@drawable/ic_dashboard" android:title="Android"/>            <item  android:icon="@drawable/ic_dashboard" android:title="iOS"/>        </menu>    </item></menu>

你可以通过设置一个OnNavigationItemSelectedListener,使用其setNavigationItemSelectedListener()来获得元素被选中的回调事件。它为你提供被点击的菜单元素 ,让你可以处理选择事件,改变复选框状态,加载新内容,关闭导航菜单,以及其他任何你想做的操作。例如这样:

private void setupDrawerContent(NavigationView navigationView) {        navigationView.setNavigationItemSelectedListener(                new NavigationView.OnNavigationItemSelectedListener() {                    @Override                    public boolean onNavigationItemSelected(MenuItem menuItem) {                        menuItem.setChecked(true);                        mDrawerLayout.closeDrawers();                        return true;                    }                });    }

Floating Action Button

floating action button 是一个负责显示界面基本操作的圆形按钮。Design library中的FloatingActionButton 实现了一个默认颜色为主题中colorAccent的悬浮操作按钮。

FloatingActionButton——FAB使用非常简单,你可以指定在加强型FrameLayout里面——CoordinatorLayout,这个我们后面再将。
关于FAB的使用,你可以把它当做一个button即可。

<android.support.design.widget.FloatingActionButton        android:layout_height="wrap_content"        android:layout_width="wrap_content"        app:layout_anchor="@id/app_bar"        app:layout_anchorGravity="bottom|right|end"        android:src="@android:drawable/ic_done"        android:layout_margin="15dp"        android:clickable="true"/>

除了一般大小的悬浮操作按钮,还有其他一些属性

  • app:fabSize :FloatingActionButton的大小,有两种赋值分别是 “mini” 和
    “normal”,默认是“normal”.
  • app:backgroundTint:FloatingActionButton的背景颜色,默认的背景颜色是Theme主题中的。
  • app:elevation
    :FloatingActionButton阴影的深度,默认是有阴影的,如果觉得默认阴影深度有点大,可以改变这个属性来修改阴影深度。

不能通过 android:background 属性来改变 FloatingActionButton的背景颜色,只能通过app:backgroundTint属性改变,因为FloatingActionButton是继承自ImageView的。
FloatingActionButton继承自ImageView,你可以使用android:src或者ImageView的任意方法,比如setImageDrawable()来设置FloatingActionButton里面的图标。

Snackbar

为一个操作提供轻量级的,快速的反馈是使用snackbar的最好时机。snackbar显示在屏幕的底部,包含了文字信息与一个可选的操作按钮。在指定时间结束之后自动消失。另外,用户还可以在超时之前将它滑动删除。
Snackbar提供了一个介于Toast和AlertDialog之间轻量级控件,包含了可以与snackbar交互的滑动删除与操作按钮,它可以很方便的提供消息的提示和动作反馈。
Snackbar的使用与Toast的使用基本相同:

Snackbar.make(view, "Snackbar comes out", Snackbar.LENGTH_LONG)                        .setAction("Action", new View.OnClickListener() {                            @Override                            public void onClick(View v) {                                Toast.makeText(                                        MainActivity.this,                                        "Toast comes out",                                        Toast.LENGTH_SHORT).show();                            }                        }).show();

需要注意的是,这里我们把第一个参数作为Snackbar显示的基准元素,而设置的Action也可以设置多个。Snackbar在出现一定时间后,就会消失,这与Toast一模一样。
具体用法见Google API Doc 官方说明

TextInputLayout

TextInputLayout作为一个父容器控件,包装了新的EditText。通常,单独的EditText会在用户输入第一个字母之后隐藏hint提示信息,但是现在你可以使用TextInputLayout 来将EditText封装起来,提示信息会变成一个显示在EditText之上的floating label,这样用户就始终知道他们现在输入的是什么。同时,如果给EditText增加监听,还可以给它增加更多的floating label。

常用方法

  • setHint():设置提示语。

  • getEditText():得到TextInputLayout中的EditView控件。

  • setErrorEnabled():设置是否可以显示错误信息。

  • setError():设置当用户输入错误时弹出的错误信息。 注意点

TextInputLayout不能单独使用,需要包裹EditView组件。
下面我们来看这与一个TextInputLayout:

XML布局

<android.support.design.widget.TextInputLayout        android:id="@+id/til_pwd"        android:layout_width="match_parent"        android:layout_height="wrap_content">        <EditText            android:layout_width="match_parent"            android:layout_height="wrap_content"/></android.support.design.widget.TextInputLayout>

一定要注意,他是把EditText包含起来的,不能单独使用。

代码

在代码中,我们给它设置监听:

final TextInputLayout textInputLayout = (TextInputLayout) findViewById(R.id.til_pwd);        EditText editText = textInputLayout.getEditText();        textInputLayout.setHint("Password");        editText.addTextChangedListener(new TextWatcher() {            @Override            public void beforeTextChanged(CharSequence s, int start, int count, int after) {                if (s.length() > 4) {                    textInputLayout.setError("Password error");                    textInputLayout.setErrorEnabled(true);                } else {                    textInputLayout.setErrorEnabled(false);                }            }            @Override            public void onTextChanged(CharSequence s, int start, int before, int count) {            }            @Override            public void afterTextChanged(Editable s) {            }        });    }

这里需要注意的是,TextInputLayout的颜色来自style中的colorAccent的颜色:

<item name="colorAccent">#1743b7</item>

TabLayout

Tab滑动切换View并不是一个新的概念,但是Google却是第一次在support库中提供了完整的支持,而且,Design library的TabLayout 既实现了固定的选项卡 - view的宽度平均分配,也实现了可滚动的选项卡 - view宽度不固定同时可以横向滚动。选项卡可以在程序中动态添加:

TabLayout tabLayout = (TabLayout) findViewById(R.id.tabs);tabLayout.addTab(tabLayout.newTab().setText("tab1"));            tabLayout.addTab(tabLayout.newTab().setText("tab2"));                    tabLayout.addTab(tabLayout.newTab().setText("tab3"));

但大部分时间我们都不会这样用,通常滑动布局都会和ViewPager配合起来使用,所以,我们需要ViewPager来帮忙:

mViewPager = (ViewPager) findViewById(R.id.viewpager);// 设置ViewPager的数据等setupViewPager();TabLayout tabLayout = (TabLayout) findViewById(R.id.tabs);tabLayout.setupWithViewPager(mViewPager);

通过一句话setupWithViewPager,我们就把ViewPager和TabLayout结合了起来。

但是如果你使用ViewPager在tab之间横向切换,你可以直接从 PagerAdapter 的 getPageTitle() 中创建选项卡,然后使用setupWithViewPager()将两者联系在一起。它可以使tab的选中事件能更新ViewPager,同时ViewPager
的页面改变能更新tab的选中状态。

AppBarLayout

AppBarLayout跟它的名字一样,把容器类的组件全部作为AppBar。like this:

这里就是把Toolbar和TabLayout放到了AppBarLayout中,让他们当做一个整体作为AppBar。

 <android.support.design.widget.AppBarLayout        android:id="@+id/appbar"        android:layout_width="match_parent"        android:layout_height="wrap_content"        android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar">        <android.support.v7.widget.Toolbar            android:id="@+id/toolbar"            android:layout_width="match_parent"            android:layout_height="?attr/actionBarSize"            android:background="?attr/colorPrimary"            app:popupTheme="@style/ThemeOverlay.AppCompat.Light"/>        <android.support.design.widget.TabLayout            android:id="@+id/tabs"            android:layout_width="match_parent"            android:layout_height="wrap_content"/>    </android.support.design.widget.AppBarLayout>

CoordinatorLayout

与众不同的视觉效果只是material design的一部分:手势同样是制作一个material design app的重要组成部分。material design的手势有很多组成部分,包括touch ripples 和 meaningful transitions 。Design library引入了CoordinatorLayout,一个从另一层面去控制子view之间触摸事件的布局,Design library中的很多控件都利用了它。CoordinatorLayout是这次新添加的一个增强型的FrameLayout。在CoordinatorLayout中,我们可以在FrameLayout的基础上完成很多新的操作。CoordinatorLayout可以说是这次support library更新的重中之重。它从另一层面去控制子view之间触摸事件的布局,Design library中的很多控件都利用了它。

Floating View

MD的一个新的特性就是增加了很多可悬浮的View,像我们前面说的Floating Action Button。我们可以把FAB放在任何地方,只需要通过:

android:layout_gravity="end|bottom"

来指定显示的位置。同时,它还提供了layout_anchor来供你设置显示坐标的锚点:

app:layout_anchor="@id/appbar"

CoordinatorLayout与Floating Action Button

一个很好的例子就是当你将FloatingActionButton作为一个子View添加进CoordinatorLayout并且将CoordinatorLayout传递给 Snackbar.make() - 在3.0极其以上的设备上,snackbar不会显示在悬浮按钮的上面,而是FloatingActionButton利用CoordinatorLayout提供的回调方法,在snackbar以动画效果进入的时候自动向上移动让出位置,并且在snackbar动画地消失的时候回到原来的位置,不需要额外的代码。

CoordinatorLayout还提供了一个layout_anchor属性,和layout_anchorGravity,一起,可以用于放置floating view,比如FloatingActionButton与其他view的相对位置。

CoordinatorLayout与app bar

CoordinatorLayout的另一个用例是 app bar(之前的actionbar)与 滚动技巧。你可能已经在自己的布局中使用了Toolbar ,它允许你更加自由的自定义其外观与布局的其余部分融为一体。Design library把这种设计带到了更高的水平:使用AppBarLayout可以让你的Toolbar与其他view(比如TabLayout的选项卡)能响应被标记了ScrollingViewBehavior的View的滚动事件。

因此,你可以创建一个如下的布局:

<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">     <! -- Your Scrollable View -->    <android.support.v7.widget.RecyclerView            android:layout_width="match_parent"            android:layout_height="match_parent"            app:layout_behavior="@string/appbar_scrolling_view_behavior" />    <android.support.design.widget.AppBarLayout            android:layout_width="match_parent"            android:layout_height="wrap_content">            <android.support.v7.widget.Toolbar                  ...                  app:layout_scrollFlags="scroll|enterAlways">            <android.support.design.widget.TabLayout                  ...                  app:layout_scrollFlags="scroll|enterAlways">     </android.support.design.widget.AppBarLayout></android.support.design.widget.CoordinatorLayout>

其中,一个可以滚动的组件,例如RecyclerView、ListView(这里需要注意的是,貌似只支持RecyclerView、ListView,如果你用一个ScrollView,是没有效果的)。如果:
1、给这个可滚动组件设置了layout_behavior
2、给另一个控件设置了layout_scrollFlags
现在,当用户滚动RecyclerView,AppBarLayout可以这样响应滚动事件:根据子view的滚动标志(scrollFlags)来控制它们如何进入(滚入屏幕)与退出(滚出屏幕)。
设置的layout_scrollFlags有如下几种选项:

  1. scroll: 所有想滚动出屏幕的view都需要设置这个flag- 没有设置这个flag的view将被固定在屏幕顶部。
  2. enterAlways: 这个flag让任意向下的滚动都会导致该view变为可见,启用快速“返回模式”。
  3. enterAlwaysCollapsed:当你的视图已经设置minHeight属性又使用此标志时,你的视图只能已最小高度进入,只有当滚动视图到达顶部时才扩大到完整高度。
  4. exitUntilCollapsed: 同样顾名思义,这个flag时定义何时退出,当你定义了一个minHeight,这个view将在滚动到达这个最小高度的时候消失。

需要注意的是,后面两种模式基本只有在CollapsingToolbarLayout才有用,而前面两种模式基本是需要一起使用的,也就是说,这些flag的使用场景,基本已经固定了。
例如我们前面例子中的,也就是这种模式:

app:layout_scrollFlags="scroll|enterAlways"

PS : 所有使用scroll flag的view都必须定义在没有使用scroll flag的view的前面,这样才能确保所有的view从顶部退出,留下固定的元素。

CoordinatorLayout与自定义view

有一件事情必须注意,那就是CoordinatorLayout并不知道FloatingActionButton或者AppBarLayout的内部工作原理 - 它只是以Coordinator.Behavior的形式提供了额外的API,该API可以使子View更好的控制触摸事件与手势以及声明它们之间的依赖,并通过onDependentViewChanged()接收回调。

可以使用CoordinatorLayout.DefaultBehavior(你的View.Behavior.class)注解或者在布局中使用app:layout_behavior=”com.example.app.你的View$Behavior”属性来定义view的默认行为。framework让任意view和CoordinatorLayout结合在一起成为了可能。

CollapsingToolbarLayout

直接添加Toolbar到AppBarLayout可以让你使用enterAlwaysCollapsed 和 exitUntilCollapsedscroll标志,但是无法控制不同元素如何响应collapsing的细节,为了达到此目的,使用CollapsingToolbarLayout.CollapsingToolbarLayout提供了一个可以折叠的Toolbar,这也是Google+、photos中的效果。Google把它做成了一个标准控件,更加方便大家使用。
这里先看一个例子:

<android.support.design.widget.AppBarLayout        android:id="@+id/appbar"        android:layout_width="match_parent"        android:layout_height="@dimen/detail_backdrop_height"        android:fitsSystemWindows="true"        android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar">        <android.support.design.widget.CollapsingToolbarLayout            android:id="@+id/collapsing_toolbar"            android:layout_width="match_parent"            android:layout_height="match_parent"            android:fitsSystemWindows="true"            app:contentScrim="?attr/colorPrimary"            app:expandedTitleMarginEnd="64dp"            app:expandedTitleMarginStart="48dp"            app:layout_scrollFlags="scroll|exitUntilCollapsed">            <ImageView                android:id="@+id/backdrop"                android:layout_width="match_parent"                android:layout_height="match_parent"                android:fitsSystemWindows="true"                android:scaleType="centerCrop"                android:src="@drawable/ic_banner"                app:layout_collapseMode="parallax"/>            <android.support.v7.widget.Toolbar                android:id="@+id/toolbar"                android:layout_width="match_parent"                android:layout_height="?attr/actionBarSize"                app:layout_collapseMode="pin"                app:popupTheme="@style/ThemeOverlay.AppCompat.Light"/>        </android.support.design.widget.CollapsingToolbarLayout>    </android.support.design.widget.AppBarLayout>

我们在CollapsingToolbarLayout中放置了一个ImageView和一个Toolbar。并把这个CollapsingToolbarLayout放到AppBarLayout中作为一个整体。在CollapsingToolbarLayout中,我们分别设置了ImageView和一个Toolbar的layout_collapseMode。
这里使用了CollapsingToolbarLayout的app:layout_collapseMode=”pin”来确保Toolbar在view折叠的时候仍然被固定在屏幕的顶部。当你让CollapsingToolbarLayout和Toolbar在一起使用的时候,title会在展开的时候自动变得大些,而在折叠的时候让字体过渡到默认值。必须注意,在这种情况下你必须在CollapsingToolbarLayout上调用setTitle(),而不是在Toolbar上。

除了固定住view,你还可以使用app:layout_collapseMode=”parallax”(以及使用app:layout_collapseParallaxMultiplier=”0.7”来设置视差因子)来实现视差滚动效果(比如CollapsingToolbarLayout里面的一个ImageView),这中情况和CollapsingToolbarLayout的app:contentScrim=”?attr/colorPrimary”属性一起配合更完美。
在这个例子中,我们同样设置了:

app:layout_scrollFlags="scroll|exitUntilCollapsed">

来接收一个:

app:layout_behavior="@string/appbar_scrolling_view_behavior">

这样才能产生滚动效果,而通过layout_collapseMode,我们就设置了滚动时内容的变化效果。

再来看一个官方的实例:

总结

经过几天的研究,Google这次提出的Android Design Support Library的意义其实并不在于给出了这些非常好的控件,其实这些控件在Github上基本都能找到相应的。它的目的在于Google给出了官方的设计指导,进一步完善了Material Design设计思想。这才是Android Design Support Library最重要的特性。当然,平心而论,这些控件的使用并不是非常的人性化,过多的封装导致整个效果不是非常的具有可定制性,但是,这毕竟是Google迈出的第一步,后面一定会更加牛逼。

代码下载

DesignSupportLibraryDemo下载
DesignSupportLibraryDemo-master下载

http://download.csdn.net/detail/wangyanguiyiyang/9197569
http://download.csdn.net/detail/wangyanguiyiyang/9197581

参考

http://blog.csdn.net/eclipsexys/article/details/46349721
http://www.jcodecraeer.com/a/anzhuokaifa/developer/2015/0531/2958.html
http://www.open-open.com/lib/view/open1433385856119.html
http://www.tuicool.com/articles/aeQrYv3
http://blog.csdn.net/qwm8777411/article/details/46365433?utm_source=tuicool#t0

http://hao.jobbole.com/materialdesignlibrary/
http://segmentfault.com/a/1190000002976409
http://www.aswifter.com/2015/06/21/andorid-material-design-support-library/
http://www.open-open.com/lib/view/open1433490948291.html#_label0

更多相关文章

  1. Flutter基础—你好,Flutter!
  2. android 2.2 迁移 android 4.0 theme style attr 浅谈
  3. Android(安卓)中自定义控件和属性(attr.xml,declare-styleable,T
  4. Android(安卓)SlidingDrawer 抽屉效果的实现
  5. Android(安卓)实现个性的ViewPager切换动画 实战PageTransformer
  6. 安卓ListView详解
  7. 表格布局(TableLayout)及重要属性
  8. android SlidingDrawer(抽屉)
  9. Android(安卓)最完善的自定义Banner轮播图之一,带给你最全面的体

随机推荐

  1. Android内嵌H5(2)
  2. android的进度条使用
  3. 面向忙碌开发者的 Android 知识点收录
  4. android.security.identity Kotlin |Java
  5. Android下 布局加边框 指定背景色 半透明
  6. android登录窗口――基础编
  7. Android控件开发之TextView
  8. Android - ToDoList(fragment) 详解
  9. Android(安卓)UI 开发入门—线性布局练习
  10. Android开发系列(一)