Android 5.X的新特性及Material Design

312 阅读7分钟

导语

说来惭愧,Android8.0奥利奥都出了,我还在学5.0的新特性,看来得再努把力了,Material Design动画确实好看,查看实例戳这里

主要内容

  • Android5.X UI设计初步
  • Palette
  • 视图与阴影
  • Tinting和Clipping
  • Android过渡动画
  • Material Design动画效果
  • Toolbar
  • Notification

具体内容

Android5.X UI设计初步

Android 5.X开始使用新的设计风格Material Design来统一整个Android系统设计风格,与之前的设计不同,这次的Material Design设计将Android带来一片全新的高度,同时Google在官网推出了新的设计指南,全面的讲解了Material Design的整个实现规范。

Material Design

材料的形态模拟

Google通过模拟自然界的形态变化、关线与阴影、纸与纸之间的空间层级关系,带来一种真实的空间感。

更加真实的动画

大色块的使用

Material Design中采用大量高饱和、适中亮度的大色块来突出界面的主次。

此外,还有更多的设计风格,比如悬浮按钮,聚焦大图,无框按钮,波纹效果等新特性,希望了解更多的Material Design设计风格的读者可以访问网站:www.google.com/design/#res…

Material Design主题

Material Design提供默认的三种主题:

@android:style/Theme.Material (dark version)        
@android:style/Theme.Material.Light (light version)     
@android:style/Theme.Material.Light.DarkActionBar

同时也提出了Color Palette的概念,让开发者自己设定系统区域的颜色。

可以通过使用自定义Style来创建自己的Color Palette颜色主题。

<resources>
    <!-- inherit from the material theme-->
    <style name="AppTheme" parent="android:Theme.Material">
        <!-- Main theme color-->
        <!-- your app branding color for the app bar-->
        <item name="colorPrimary">#BEBEBE</item>
        <!-- derker variant for thr status bar and contextual app bars-->
        <item name="colorPrimaryDark">#FF5AEBFF</item>
        <!--theme ui controls like checkBoxs and text fields-->
        <item name="colorAccent">#FFFF4130</item>
    </style>
</resources>

效果图

Palette

Android5.X使用Palette来提取颜色,从而让主题能够动态适应当前页面的色调。

Android内置了几种提取颜色的种类:

  • Vibrant(充满活力的)
  • Vibrant dark(充满活力的黑)
  • Vibrant light(充满活力的白)
  • Muted(柔和的)
  • Muted dark(柔和的黑)
  • Muted light(柔和的白)

使用Palette需要在Dependencies中添加依赖:

compile 'com.android.support:palette-v7:21.0.2'

这可以给Palette传进一个Bitmap对象,并调用它的Palette.generate()静态方法或者Palette.generateAsync()方法创建一个Palette。

下面例子演示如何通过加载图片的柔和色调来改变状态栏和Actionbar的色调:

public class PaletteActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.palette);
        Bitmap bitmap = BitmapFactory.decodeResource(getResources(),
                R.drawable.test);
        // 创建Palette对象
        Palette.generateAsync(bitmap, new Palette.PaletteAsyncListener() {
            @Override
            public void onGenerated(Palette palette) {
                // 通过Palette来获取对应的色调
                Palette.Swatch vibrant =
                        palette.getDarkVibrantSwatch();
                // 将颜色设置给相应的组件
                getSupportActionBar().setBackgroundDrawable(
                        new ColorDrawable(vibrant.getRgb()));
                Window window = getWindow();
                window.setStatusBarColor(vibrant.getRgb());
            }
        });
    }
}

查看效果图:

效果图

视图与阴影

Material Design最重要的特点就是拟物扁平化。

阴影效果

Android5.X在以外的View中只有x和y的方向上添加了z方向,看图。

阴影效果

View的z值由两部分组成:

Z = elevation + translationZ;

通常可以在XML布局文件中设置View的视图高度:

android:elevation="XXdp"

下面通过实例演示不同视图高度的效果:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

    <TextView
        android:layout_width="100dp"
        android:layout_height="100dp"
        android:layout_margin="10dp"
        android:background="@mipmap/ic_launcher" />

    <TextView
        android:layout_width="100dp"
        android:layout_height="100dp"
        android:layout_margin="10dp"
        android:background="@mipmap/ic_launcher"
        android:elevation="2dp" />

    <TextView
        android:layout_width="100dp"
        android:layout_height="100dp"
        android:layout_margin="10dp"
        android:background="@mipmap/ic_launcher"
        android:elevation="10dp" />
</LinearLayout>

效果图:

效果图

在程序中也可以用代码变换视图高度:

view.setTranslationZ(xxx);

通常和还可以用属性动画来改变视图高度:

if(flag){
    view.animate().translationZ(100);
    flag = false;
}else {
    view.animate().translationZ(0);
    flag = true;
}

Tinting和Clipping

Android5.X提供了两个对操作图像的新功能:Tinting和Clipping。

Tinting(着色)

下面有例子说明,注意tint和tintMode属性:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

    <ImageView
        android:layout_width="100dp"
        android:layout_height="100dp"
        android:layout_gravity="center"
        android:elevation="5dp"
        android:src="@mipmap/ic_launcher" />

    <ImageView
        android:layout_width="100dp"
        android:layout_height="100dp"
        android:layout_gravity="center"
        android:elevation="5dp"
        android:src="@mipmap/ic_launcher"
        android:tint="@android:color/holo_blue_bright" />

    <ImageView
        android:layout_width="100dp"
        android:layout_height="100dp"
        android:layout_gravity="center"
        android:elevation="5dp"
        android:src="@mipmap/ic_launcher"
        android:tint="@android:color/holo_blue_bright"
        android:tintMode="add" />

    <ImageView
        android:layout_width="100dp"
        android:layout_height="100dp"
        android:layout_gravity="center"
        android:elevation="5dp"
        android:src="@mipmap/ic_launcher"
        android:tint="@android:color/holo_blue_bright"
        android:tintMode="multiply" />

</LinearLayout>

效果图:

效果图

Clipping(裁剪)

使用Clipping,首先需要使用ViewOutlineProvider来修改outline,然后再通过setOutlinProvider将outline作用给视图。

下面通过例子理解Clipping:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:gravity="center"
    android:orientation="vertical">

    <TextView
        android:id="@+id/tv_rect"
        android:layout_width="100dp"
        android:layout_height="100dp"
        android:layout_marginTop="20dp"
        android:elevation="1dp"
        android:gravity="center" />

    <TextView
        android:id="@+id/tv_circle"
        android:layout_width="100dp"
        android:layout_height="100dp"
        android:layout_marginTop="20dp"
        android:elevation="1dp"
        android:gravity="center" />

</LinearLayout>

在代码中:

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        View v1 = findViewById(R.id.tv_rect);
        View v2 = findViewById(R.id.tv_circle);
        //获取Outline
        ViewOutlineProvider viewOutlineProvider1 = new ViewOutlineProvider() {
            @Override
            public void getOutline(View view, Outline outline) {
                //修改outline为特定形状
                outline.setRoundRect(0, 0, view.getWidth(), view.getHeight(), 30);
            }
        };
        //获取Outline
        ViewOutlineProvider viewOutlineProvider2 = new ViewOutlineProvider() {
            @Override
            public void getOutline(View view, Outline outline) {
                //修改outline为特定形状
                outline.setOval(0, 0, view.getWidth(), view.getHeight());
            }
        };
        //重新设置形状
        v1.setOutlineProvider(viewOutlineProvider1);
        v2.setOutlineProvider(viewOutlineProvider2);
    }
}

效果图:

效果图

Android过渡动画

在Activity之间的跳转中,通过overridePendingtransition(int inId,int outId)这个方法给Activity添加一些切换动画,效果也是差强人意。

过渡动画

Android5.X提供了三种Transition类型的动画:

  • 进入:一个进入的过渡动画决定Activity中的所有视图怎么进入屏幕。
  • 退出:一个退出的过渡动画决定Activity中的所有视图怎么退出屏幕。
  • 共享元素:一个共享元素过渡动画决定两个Activity之间的过渡,怎么共享他们的视图。

其中,进入和退出效果包括:

  • explode(分解)一一从屏幕中间进或出,移动视图。
  • slide(滑动)——从屏幕边缘进或出,移动视图。
  • fade(淡出) 一一通过改变屏幕上视图的不透明度达到添加或者移除视图。

共享元素包括(简单的说ActivityA的指定的View不会消失,带着View跳转到ActivityB中):

  • changeBounds——改变目标视图的布局边界。
  • changeClipBounds——裁剪目标视图边界。
  • changeTransfrom——改变目标视图的缩放比例和旋转角度。
  • changeImageTransfrom——改变目标图片的大小和缩放比例。

这里比如ActivityA跳转到ActivityB,运用这三种过渡动画,则在ActivityA中修改:

startActivity(intent, ActivityOptions.makeSceneTransitionAnimation(this).toBundle());

而在ActivityB,只需要设置以下代码:

getWindow().requestFeature(Window.FEATURE_CONTENT_TRANSITIONS);

或者在ActivityB的样式文件设置如下代码:

<item name="android:windowContentTransitions">true</item>

那么接下来可以设置进入ActivityB的动画效果:

getWindow().setEnterTransition(new Explode());
getWindow().setEnterTransition(new Slide());
getWindow().setEnterTransition(new Fade());

或者是设置离开ActivityB的动画效果:

getWindow().setExitTransition(new Explode());
getWindow().setExitTransition(new Slide());
getWindow().setExitTransition(new Fade());

三种普通切换动画的效果图:

效果图

下面是共享元素的使用,首先在ActivityA中设置共享元素的属性:

android:transitionName="XXX"

同时在ActivityB中设置相同的共享元素的属性:

android:transitionName="XXX"

在代码中使用共享元素,首先是单个共享元素:

startActivity(intent, ActivityOptions.makeSceneTransitionAnimation(this,view,"share").toBundle());

或者一个视图中有多个共享元素,通过Pair.create()来创建多个共享元素:

startActivity(intent, ActivityOptions.makeSceneTransitionAnimation(this, 
        Pair.create(view,"share"),Pair.create(fab,"fab")).toBundle());

共享元素的效果图:

效果图

Material Design动画效果

Ripple效果

Ripple效果:点击后的波纹效果,可以通过代码设置波纹背景。

//波纹有边界
android:background="?android:attr/selectableItemBackground"
//波纹无边界
android:background="?android:attr/selectableItemBackgroundBorderless"

下面通过例子来演示一下这两个效果:

<?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="match_parent"
    android:background="@android:color/holo_blue_light"
    android:gravity="center"
    android:orientation="vertical">

    <Button
        android:layout_width="100dp"
        android:layout_height="100dp"
        android:background="?android:attr/selectableItemBackground"
        android:text="有界波纹"
        android:textColor="@android:color/white" />


    <Button
        android:layout_width="100dp"
        android:layout_height="100dp"
        android:background="?android:attr/selectableItemBackgroundBorderless"
        android:text="无界波纹"
        android:textColor="@android:color/white" />

</LinearLayout>

效果图:

效果图

同样的,也可以通过XML来声明一个ripple,然后在布局文件中使用:

<?xml version="1.0" encoding="utf-8"?>
<ripple xmlns:android="http://schemas.android.com/apk/res/android"
    android:color="?android:colorPrimary">
    <item>
        <shape android:shape="oval">
            <solid android:color="?android:colorAccent" />
        </shape>
    </item>
</ripple>
<Button
    android:layout_width="100dp"
    android:layout_height="100dp"
    android:background="@drawable/ripple" />

效果图:

效果图

Circular Reveal

这个动画效果具体变现为一个View以圆形的形式展开,揭示出来,通过ViewAnimationUtils.createCircularReveal()来创建动画,代码如下:

public static Animator createCircularReveal(View view, int centerX, 
int centerY, float startRadius, float endRadius) {
     return new RevealAnimator(view,centerX,centerY,startRadius,endRadius);
}

RevealAnimator的使用特别简单,主要就是几个关键的坐标点:

  • centerX 动画开始的中心点X
  • centerY 动画开始的中心点Y
  • startRadius 动画开始半径
  • endRadius 动画结束半径

接下来我们来看一下例子,了解下RevealAnimator的使用,首先用XML创建一个圆和方形:

<?xml version="1.0" encoding="utf-8"?>
<ripple xmlns:android="http://schemas.android.com/apk/res/android"
    android:color="?android:colorControlHighlight">
    <item>
        <shape android:shape="oval">
            <solid android:color="#738ffe" />
        </shape>
    </item>
</ripple>
<?xml version="1.0" encoding="utf-8"?>
<ripple xmlns:android="http://schemas.android.com/apk/res/android"
    android:color="?android:colorControlHighlight">
    <item>
        <shape android:shape="rectangle">
            <solid android:color="#738ffe" />
        </shape>
    </item>
</ripple>

然后在布局文件中使用这两个图形:

<?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="match_parent"
    android:orientation="vertical"
    android:gravity="center">

    <ImageView
        android:id="@+id/oval"
        android:layout_width="100dp"
        android:layout_height="100dp"
        android:background="@drawable/oval" />

    <ImageView
        android:id="@+id/rect"
        android:layout_width="100dp"
        android:layout_height="100dp"
        android:background="@drawable/rect" />

</LinearLayout>

主程序:

public class CircularReveal extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_circular_reveal);

        final View oval = findViewById(R.id.oval);
        oval.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Animator animator = ViewAnimationUtils.createCircularReveal(oval,
                        oval.getWidth() / 2, oval.getHeight() / 2, oval.getWidth(), 0);
                animator.setInterpolator(new AccelerateDecelerateInterpolator());
                animator.setDuration(2000);
                animator.start();
            }
        });

        final View rect = findViewById(R.id.rect);
        rect.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Animator animator = ViewAnimationUtils.createCircularReveal(rect, 0, 0, 0,
                        (float) Math.hypot(rect.getWidth(), rect.getHeight()));
                animator.setInterpolator(new AccelerateInterpolator());
                animator.setDuration(2000);
                animator.start();
            }
        });
    }
}

效果图:

效果图

View state changes Animation
  • StateListAnimator:视图动画效果,以前的Selector用来修改背景达到反馈效果,现在支持Selector使用动画效果。

在XML定义一个StateListAnimator,添加到Selector中:

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:state_pressed="true">
        <set>
            <objectAnimator android:property="rotationX" 
        android:duration="@android:integer/config_shortAnimTime" 
        android:valueTo="360" 
        android:valuyeType="floatType" />
        </set>
    </item>
    <item android:state_pressed="false">
        <set>
            <objectAnimator android:property="rotationX"
        android:duration="@android:integer/config_shortAnimTime" 
        android:valueTo="0" 
        android:valuyeType="floatType" />
        </set>
    </item>
</selector>

在布局文件中直接使用:

<Button
    android:layout_width="200dp"
    android:layout_height="200dp"
    android:background="@drawable/anim_change" />

特别要注意:Animator是要开启的,所以必须在主代码中使用AnimatorInflater.loadStateListAnimator()方法,并且通过View.setStateListAnimator()方法分配到视图中。

  • animated-selector:同样作为一种状态改变的动画效果Selector。 首先得有一套状态变换图:

然后在XML中定义这些图片组合:

<animated-selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item
        android:id="@+id/state_on"
        android:state_checked="true">
        <bitmap android:src="@drawable/ic_done_anim_030" />
    </item>
    <item android:id="@+id/state_off">
        <bitmap android:src="@drawable/ic_plus_anim_030" />
    </item>
    <transition
        android:fromId="@+id/state_on"
        android:toId="@+id/state_off">
        <animation-list>
            <item android:duration="16">
                <bitmap android:src="@drawable/ic_plus_anim_000" />
            </item>
            <item android:duration="16">
                <bitmap android:src="@drawable/ic_plus_anim_001" />
            </item>
            <item android:duration="16">
                <bitmap android:src="@drawable/ic_plus_anim_002" />
            </item>
            <item android:duration="16">
                <bitmap android:src="@drawable/ic_plus_anim_003" />
            </item>
            <item android:duration="16">
                <bitmap android:src="@drawable/ic_plus_anim_004" />
            </item>
            <item android:duration="16">
                <bitmap android:src="@drawable/ic_plus_anim_005" />
            </item>
            <item android:duration="16">
                <bitmap android:src="@drawable/ic_plus_anim_006" />
            </item>
            <item android:duration="16">
                <bitmap android:src="@drawable/ic_plus_anim_007" />
            </item>
            <item android:duration="16">
                <bitmap android:src="@drawable/ic_plus_anim_008" />
            </item>
            <item android:duration="16">
                <bitmap android:src="@drawable/ic_plus_anim_009" />
            </item>
            <item android:duration="16">
                <bitmap android:src="@drawable/ic_plus_anim_010" />
            </item>
            <item android:duration="16">
                <bitmap android:src="@drawable/ic_plus_anim_011" />
            </item>
            <item android:duration="16">
                <bitmap android:src="@drawable/ic_plus_anim_012" />
            </item>
            <item android:duration="16">
                <bitmap android:src="@drawable/ic_plus_anim_013" />
            </item>
            <item android:duration="16">
                <bitmap android:src="@drawable/ic_plus_anim_014" />
            </item>
            <item android:duration="16">
                <bitmap android:src="@drawable/ic_plus_anim_015" />
            </item>
            <item android:duration="16">
                <bitmap android:src="@drawable/ic_plus_anim_016" />
            </item>
            <item android:duration="16">
                <bitmap android:src="@drawable/ic_plus_anim_017" />
            </item>
            <item android:duration="16">
                <bitmap android:src="@drawable/ic_plus_anim_018" />
            </item>
            <item android:duration="16">
                <bitmap android:src="@drawable/ic_plus_anim_019" />
            </item>
            <item android:duration="16">
                <bitmap android:src="@drawable/ic_plus_anim_020" />
            </item>
            <item android:duration="16">
                <bitmap android:src="@drawable/ic_plus_anim_021" />
            </item>
            <item android:duration="16">
                <bitmap android:src="@drawable/ic_plus_anim_022" />
            </item>
            <item android:duration="16">
                <bitmap android:src="@drawable/ic_plus_anim_023" />
            </item>
            <item android:duration="16">
                <bitmap android:src="@drawable/ic_plus_anim_024" />
            </item>
            <item android:duration="16">
                <bitmap android:src="@drawable/ic_plus_anim_025" />
            </item>
            <item android:duration="16">
                <bitmap android:src="@drawable/ic_plus_anim_026" />
            </item>
            <item android:duration="16">
                <bitmap android:src="@drawable/ic_plus_anim_027" />
            </item>
            <item android:duration="16">
                <bitmap android:src="@drawable/ic_plus_anim_028" />
            </item>
            <item android:duration="16">
                <bitmap android:src="@drawable/ic_plus_anim_029" />
            </item>
            <item android:duration="16">
                <bitmap android:src="@drawable/ic_plus_anim_030" />
            </item>
        </animation-list>
    </transition>
    <transition
        android:fromId="@+id/state_off"
        android:toId="@+id/state_on">
        <animation-list>
            <item android:duration="16">
                <bitmap android:src="@drawable/ic_done_anim_000" />
            </item>
            <item android:duration="16">
                <bitmap android:src="@drawable/ic_done_anim_001" />
            </item>
            <item android:duration="16">
                <bitmap android:src="@drawable/ic_done_anim_002" />
            </item>
            <item android:duration="16">
                <bitmap android:src="@drawable/ic_done_anim_003" />
            </item>
            <item android:duration="16">
                <bitmap android:src="@drawable/ic_done_anim_004" />
            </item>
            <item android:duration="16">
                <bitmap android:src="@drawable/ic_done_anim_005" />
            </item>
            <item android:duration="16">
                <bitmap android:src="@drawable/ic_done_anim_006" />
            </item>
            <item android:duration="16">
                <bitmap android:src="@drawable/ic_done_anim_007" />
            </item>
            <item android:duration="16">
                <bitmap android:src="@drawable/ic_done_anim_008" />
            </item>
            <item android:duration="16">
                <bitmap android:src="@drawable/ic_done_anim_009" />
            </item>
            <item android:duration="16">
                <bitmap android:src="@drawable/ic_done_anim_010" />
            </item>
            <item android:duration="16">
                <bitmap android:src="@drawable/ic_done_anim_011" />
            </item>
            <item android:duration="16">
                <bitmap android:src="@drawable/ic_done_anim_012" />
            </item>
            <item android:duration="16">
                <bitmap android:src="@drawable/ic_done_anim_013" />
            </item>
            <item android:duration="16">
                <bitmap android:src="@drawable/ic_done_anim_014" />
            </item>
            <item android:duration="16">
                <bitmap android:src="@drawable/ic_done_anim_015" />
            </item>
            <item android:duration="16">
                <bitmap android:src="@drawable/ic_done_anim_016" />
            </item>
            <item android:duration="16">
                <bitmap android:src="@drawable/ic_done_anim_017" />
            </item>
            <item android:duration="16">
                <bitmap android:src="@drawable/ic_done_anim_018" />
            </item>
            <item android:duration="16">
                <bitmap android:src="@drawable/ic_done_anim_019" />
            </item>
            <item android:duration="16">
                <bitmap android:src="@drawable/ic_done_anim_020" />
            </item>
            <item android:duration="16">
                <bitmap android:src="@drawable/ic_done_anim_021" />
            </item>
            <item android:duration="16">
                <bitmap android:src="@drawable/ic_done_anim_022" />
            </item>
            <item android:duration="16">
                <bitmap android:src="@drawable/ic_done_anim_023" />
            </item>
            <item android:duration="16">
                <bitmap android:src="@drawable/ic_done_anim_024" />
            </item>
            <item android:duration="16">
                <bitmap android:src="@drawable/ic_done_anim_025" />
            </item>
            <item android:duration="16">
                <bitmap android:src="@drawable/ic_done_anim_026" />
            </item>
            <item android:duration="16">
                <bitmap android:src="@drawable/ic_done_anim_027" />
            </item>
            <item android:duration="16">
                <bitmap android:src="@drawable/ic_done_anim_028" />
            </item>
            <item android:duration="16">
                <bitmap android:src="@drawable/ic_done_anim_029" />
            </item>
            <item android:duration="16">
                <bitmap android:src="@drawable/ic_done_anim_030" />
            </item>
        </animation-list>
    </transition>
</animated-selector>

最后在主程序中使用即可:

public class AnimatedSelectorActivity extends AppCompatActivity {

    private boolean mIsCheck;
    private static final int[] STATE_CHECKED = new int[]{
            android.R.attr.state_checked};
    private static final int[] STATE_UNCHECKED = new int[]{};
    private ImageView mImageView;
    private Drawable mDrawable;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_animated_selector);
        mImageView = (ImageView) findViewById(R.id.image);
        mDrawable = getResources().getDrawable(
                R.drawable.fab_anim);
        mImageView.setImageDrawable(mDrawable);
    }

    public void anim(View view) {
        if (mIsCheck) {
            mImageView.setImageState(STATE_UNCHECKED, true);
            mIsCheck = false;
        } else {
            mImageView.setImageState(STATE_CHECKED, true);
            mIsCheck = true;
        }
    }
}

效果图:

效果图

Toolbar

Toolbar与ActionBar最大的区别就是Toolbar更加自由、可控,这也是Google逐渐使用Toolbar替代Actionbar的原因,使用Toolbar必须引入appcompat-v7包,并设置主题为NoActionBar,使用以下代码进行设置:

<resources>

    <style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">
        <!-- toolbar颜色-->
        <item name="colorPrimary">@color/colorPrimary</item>
        <!-- 状态栏颜色-->
        <item name="colorPrimaryDark">@color/colorPrimaryDark</item>
        <!-- 窗口的背景颜色-->
        <item name="android:windowBackground">@android:color/white</item>
        <!-- add SearchView-->
        <item name="android:searchViewStyle">@style/MySearchView</item>
    </style>

    <style name="MySearchView" parent="Widget.AppCompat.SearchView" />
</resources>

Notification

Android5.0对Notification进行了优化:

  • 长按Notification可以显示消息来源。
  • 锁屏状态下,可以看到Notification的通知。

Notification分为三个等级:

  • VISIBILITY_PRIVATE:表明只有当没有锁屏的时候会显示。
  • VISIBILITY_PUBLIC:表明在任何情况下都会显示。
  • VISIBILITY_SECRET:表明在pin、password等安全锁和没有锁屏的情况下显示。

设置Notification的等级非常简单,只需增加一句:

builder.setVisibility(Notification.VISIBILITY_PUBLIC);

同时,Notificatio还提供了其他方法:

  • 设置Notification背景颜色
builder.setColor(Color.RED);
  • 设置Notification的category接口,用来确定Notification的显示位置
builder.setCategory(Notification.CATEGORY_MESSAGE);