android5.0新特性基础示例

1. Android5.0新特性

1.1. Material Design(MD)简介

Material Design材料设计,是的一种新的设计风格,谷歌希望寄由此来统一各种平台上的应用外观和用户体验。

官网介绍:

http://www.google.com/design/spec/material-design/introduction.html

1.2. 主题样式

系统自带的三个材料风格主题:

@android:style/Theme.Material (深色)

@android:style/Theme.Material.Light (亮色)

@android:style/Theme.Material.Light.DarkActionBar (亮色,actionbar为深色)

l 如何使用材料风格主题?

官方资料: http://developer.android.com/training/material/theme.html 或

           file:///D:/Android/android-sdk-windows/docs/training/material/theme.html

颜色取色器: 

           http://www.materialpalette.com/

(1)定义主题:

<!-- api21以上版本生效 -->

<style name="RedTheme" parent="android:Theme.Material">
    <!-- 状态栏颜色,会被statusBarColor效果覆盖-->
    <item name="android:colorPrimaryDark">@color/status_red</item>
    <!-- 状态栏颜色,继承自colorPrimaryDark -->
    <item name="android:statusBarColor">@color/status_red</item>
    <!-- actionBar颜色 -->
    <item name="android:colorPrimary">@color/action_red</item>

    <!-- 窗口背景颜色 -->
    <item name="android:windowBackground">@color/window_bg_red</item>
    <!-- 底部导航栏颜色 -->
    <item name="android:navigationBarColor">@color/navigation_red</item>

    <!-- 前景色:ListView的分割线颜色,switch滑动区域色-->
    <item name="android:colorForeground">@color/fg_red</item>
    <!-- 背景色:popMenu的背景色 -->
    <item name="android:colorBackground">@color/bg_red</item>

    <!-- 控件默认颜色 ,效果会被colorControlActivated取代  -->
    <item name="android:colorAccent">@color/control_activated_red</item>
    <!-- 控件默认状态时的颜色  -->
    <item name="android:colorControlNormal">@color/control_normal_red</item>
    <!-- 控件按下时的颜色,会影响水波纹效果,继承自colorAccent  -->
    <item name="android:colorControlHighlight">@color/control_highlight_red</item>
    <!-- 控件选中时(selectedchecked)的颜色 -->
    <item name="android:colorControlActivated">@color/control_activated_red</item>

    <!-- Button的默认背景颜色 -->
    <item name="android:colorButtonNormal">@color/button_normal_red</item>
    <!-- ButtontextView的文字颜色  -->
    <item name="android:textColor">@color/white_text</item>
    <!-- RadioButton checkbox等控件的文字 -->
    <item name="android:textColorPrimaryDisableOnly">@color/white_text</item>
    <!-- actionBar的标题文字颜色 -->
    <item name="android:textColorPrimary">@color/white_text</item>
</style>

(2)使用主题:(有两种方式)

     a) 配置文件中配置

<application
    android:theme="@style/RedTheme">

     b) 代码方式:

protected void onCreate(Bundle savedInstanceState) {
    setTheme(R.style.RedTheme);  // 设置主题 
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
}

l 通过V7(部分)包兼容低版本

(1)添加support v7

     在build.gradledependencies节点下添加:

compile 'com.android.support:appcompat-v7:23.0.3'

(2)使用Theme.AppCompat主题

<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar"

(3)继承AppCompatActivity

 界面不再继承 Activity, FragmentActivity ActionBarActivity, 而是继承AppCompatActivity, 目的是为了将MD的风格,

 及Toolbar等新的特效兼容到低版本。

注意:V7包只是兼容了材料主题的部分功能,一些主题样式目前在低版本还无法使用

      如:导航栏样式修改;

1.3. 高度与阴影

n 阴影大小Z = elevation + translationZ  (elevation是相对于父控件的高度

n 比父控件的高宽小,才能显示阴影

n 高度(阴影大小)决定了View的遮盖关系

阴影效果设置:

android:elevation="4dp"     

android:translationZ="4dp"

1.4. 轮廓(outlineProvider属性

n 指定控件的轮廓

// 默认为background

android:outlineProvider="none|background|bounds|paddedBounds"

n 若控件背景为半透明的shape或图片,则不会产生阴影。需要在代码中设置。

// 代码设置轮廓
circle1.setOutlineProvider(new ViewOutlineProvider() {
    public void getOutline(View view, Outline outline) {
        // 可以指定圆形,矩形,圆角矩形,path
        outline.setOval(00, view.getWidth(), view.getHeight());
    }
});

// 代码设置轮廓:减少轮廓
circle2.setOutlineProvider(new ViewOutlineProvider() {
    public void getOutline(View view, Outline outline) {
        int padding = dp2px(5);
        outline.setOval(padding, padding,
                view.getWidth() - padding,
                view.getHeight() - padding);
    }
});

1.5. 裁剪

n 裁剪视图可以轻松改变视图形状;

n 裁剪方法:

通过mView.clipToOutline(true)或android:clipToOutline="true"

将视图裁剪成轮廓指定形状

n 不是所有轮廓都可裁剪:

仅有矩形、圆形和圆角矩形轮廓支持裁剪,Path、椭圆无法进行裁剪;

可通过Outline.canClip()判断指定的轮廓是否可裁剪:

mTextView.setOutlineProvider(new ViewOutlineProvider() {
    public void getOutline(View view, Outline outline) {

// 指定轮廓:圆形
outline.setOval(00, view.getWidth(), view.getHeight());

        // 指定轮廓:圆角矩形
        // outline.setRoundRect(00, view.getWidth(), view.getHeight(), dp2px(10));

        

        cut2.setText("判断是否可裁剪: " + outline.canClip());
    }
});
mTextView.setClipToOutline(true); // 裁剪

1.6. 染色(Tint

n 十六种PorterDuffXfermode(参考ApiDemographics / xfermodes

   

n 八种模式tint模式

android:background="@drawable/ring"
android:backgroundTint="@color/color_tint"    // tint颜色
android:backgroundTintMode="add"// 染色模式,共8种模式

n 一张图片实现选择器:

按下的样式:drawable/ring_tint.xml

<?xml version="1.0" encoding="utf-8"?>
<bitmap xmlns:android="http://schemas.android.com/apk/res/android"
    android:src="@drawable/ring"
    android:tint="#5677fc"
    android:tintMode="multiply" />

选择器的定义:

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:drawable="@drawable/ring_tint" android:state_pressed="true" />
    <item android:drawable="@drawable/ring" />
</selector>

1.7. 调色板(Palette) 

Palette:调色板,取色板,它是v7包中的类: android.support.v7.graphics.Palette

可以用来获取一张图片中的颜色值。

Vibrant         鲜艳的

Vibrant dark    鲜艳的暗色

Vibrant light    鲜艳的亮色

Muted          柔和的

Muted dark     柔和的暗色

Muted light     柔和的亮色

Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.palette);

// 对图片取色是一个比较消耗性能的操作,其内部会在子线程中运行。
Palette.from(bitmap).generate(new Palette.PaletteAsyncListener() {
   public void onGenerated(Palette palette) {
      v.setBackgroundColor(palette.getVibrantColor(Color.BLACK));
      vd.setBackgroundColor(palette.getDarkVibrantColor(Color.BLACK));
      vl.setBackgroundColor(palette.getLightVibrantColor(Color.BLACK));
      m.setBackgroundColor(palette.getMutedColor(Color.BLACK));
      md.setBackgroundColor(palette.getDarkMutedColor(Color.BLACK));
      ml.setBackgroundColor(palette.getLightMutedColor(Color.BLACK));
   }
});

1.8. 矢量图

l SVG: 矢量图可以用一个根节点为svgxml文件表示;    

l w3矢量图文档:  https://www.w3.org/TR/SVG11/paths.html

l 绘制矢量图:  http://editor.method.ac/ 

l Svg --> vectorhttp://inloop.github.io/svg2android/

要在android中显示矢量图,需要把svg文件转换为vector文件

<LinearLayout
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:gravity="center"
    android:orientation="horizontal">
    <ImageView
        android:layout_width="50dp"
        android:layout_height="50dp"
        android:background="@drawable/heart" />
    <ImageView
        android:layout_width="200dp"
        android:layout_height="200dp"
        android:background="@drawable/heart" />
</LinearLayout>

// drawable/heart.xml

<?xml version="1.0" encoding="utf-8"?>
<vector xmlns:android="http://schemas.android.com/apk/res/android"
    android:width="100dp"
    android:height="100dp"
    android:viewportHeight="40"
    android:viewportWidth="40">
    <path
        android:fillColor="#ff00ff"
        android:pathData="M20.5,9.5
                        c-1.955,0,-3.83,1.268,-4.5,3
                        c-0.67,-1.732,-2.547,-3,-4.5,-3
                        C8.957,9.5,7,11.432,7,14
                        c0,3.53,3.793,6.257,9,11.5
                        c5.207,-5.242,9,-7.97,9,-11.5
                        C25,11.432,23.043,9.5,20.5,9.5z"/>
</vector>

1.9. 全新动画

Material Design设计中,为用户与app交互反馈他们的动作行为和提供了视觉上的连贯性。Material主题为控件和Activity的过渡提供了一些默认的动画,在android L上,允许自定义这些动画:

Touch feedback  触摸反馈动画 (水波纹动画,涟漪动画)

Circular Reveal animation  圆形揭示动画

Path-based animations 基于路径的动画(Curved motion曲线运动

View state changes  视图状态动画

Vector Drawables 矢量图动画

Activity transitions Activity转场动画

1.9.1. 触摸反馈Touch feedback

参见http://developer.android.com/reference/android/graphics/drawable/RippleDrawable.html

Button自带水波纹动画
    1.  默认效果
    2.  android:background="?android:selectableItemBackground"
    3.  android:background="?android:selectableItemBackgroundBorderless"

全局的水波纹样式定义:

<item name="android:colorControlHighlight">@color/bg_red</item>

按钮字母大写问题解决:

<item name="android:textAllCaps">false</item>

单独给某个控件定义水波纹效果:

<?xml version="1.0" encoding="utf-8"?>
<ripple xmlns:android="http://schemas.android.com/apk/res/android"
    android:color="@color/bg_red">
</ripple>

1.9.2. 圆形揭示动画Circular Reveal animation 

参见http://developer.android.com/training/material/animations.html#Reveal

ViewAnimationUtils.createCircularReveal(View, xO, yO, startR, endR);  

// 例子1

Animator animator1 = ViewAnimationUtils.createCircularReveal(bt1,
      bt1.getWidth() / 2bt1.getHeight() / 2,
      bt1.getWidth(), 0);
animator1.setInterpolator(new LinearInterpolator());
animator1.setDuration(3000);
animator1.start();

// 例子2

Animator animator2 = ViewAnimationUtils.createCircularReveal(bt2,
      0bt2.getHeight(), 

      0, (float) Math.hypot(bt2.getWidth(), bt2.getHeight()));
animator2.setDuration(3000);
animator2.start();

1.9.3. 基于路径的动画Path-based animations 

参见 http://developer.android.com/training/material/animations.html#CurvedMotion

private void curved(){
   Path path = new Path();    // 创建路径
   path.moveTo(curved.getX(), curved.getY());

   path.lineTo(dp2px(100), dp2px(100)); // a
   path.lineTo(dp2px(200), dp2px(100)); // b
   path.lineTo(dp2px(200), dp2px(200)); // c
   path.lineTo(dp2px(100), dp2px(200)); // d
   path.lineTo(dp2px(100), dp2px(100)); // a

   path.lineTo(curved.getX(), curved.getY());

   ObjectAnimator mAnimator = ObjectAnimator.ofFloat(curved, View.X, View.Y, path);
   mAnimator.setDuration(4000);
   mAnimator.start();
}

1.9.4. 状态动画View state changes

参见http://developer.android.com/training/material/animations.html#ViewState  

// 例子1

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item
        android:state_pressed="true"
        android:drawable="@color/control_highlight_blue_grey">
        <set>
            <objectAnimator android:propertyName="translationZ"
                            android:duration="200"
                            android:valueTo="10dp"
                            android:valueType="floatType"/>
            <objectAnimator android:propertyName="scaleX"
                            android:duration="200"
                            android:valueTo="0.8"
                            android:valueType="floatType"/>
            <objectAnimator android:propertyName="scaleY"
                            android:duration="200"
                            android:valueTo="0.8"
                            android:valueType="floatType"/>
        </set>
    </item>
    <item
        android:state_pressed="false"
        android:drawable="@color/button_normal_blue_grey">
        <set>
            <objectAnimator android:propertyName="translationZ"
                            android:duration="200"
                            android:valueTo="0"
                            android:valueType="floatType"/>
            <objectAnimator android:propertyName="scaleX"
                            android:duration="200"
                            android:valueTo="1"
                            android:valueType="floatType"/>
            <objectAnimator android:propertyName="scaleY"
                            android:duration="200"
                            android:valueTo="1"
                            android:valueType="floatType"/>
        </set>
    </item>
</selector>

<TextView
android:clickable="true"
android:background="@drawable/state_anim"
android:stateListAnimator="@drawable/state_anim"/>

// 例子2

<?xml version="1.0" encoding="utf-8"?>
<animated-selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item
        android:id="@+id/pressed"
        android:drawable="@drawable/btn_check_15"
        android:state_pressed="true" />
    <item
        android:id="@+id/normal"
        android:drawable="@drawable/btn_check_0" />
    <transition
        android:fromId="@id/normal"
        android:toId="@id/pressed">
        <animation-list>
            <item
                android:drawable="@drawable/btn_check_0"
                android:duration="100" />
            <item
                android:drawable="@drawable/btn_check_1"
                android:duration="100" />
            <item
                android:drawable="@drawable/btn_check_2"
                android:duration="100" />
            ...
        </animation-list>
    </transition>
</animated-selector>

<Button
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:background="@drawable/state_list" />

1.9.5. 矢量图动画Vector Drawables

参见http://developer.android.com/training/material/animations.html#AnimVector


1. 定义矢量图Vector,需要对路径设置名称

<vector xmlns:android="http://schemas.android.com/apk/res/android"
    android:width="200dp"
    android:height="200dp"
    android:viewportHeight="1000"
    android:viewportWidth="1000">
    <group
        android:name="rotation"
        android:pivotX="500.0"
        android:pivotY="500.0"
        android:rotation="0.0">
        <path
            android:name="vector"
            android:fillColor="#00ffff"
            android:pathData="M67,750 L500,0  500,0  933,750 67,750  M146,853 A 0.1,500 0 0 1 146,148 M146,148 A 500,0.1 0 0 1 851,148  M851,148 A 0.1,500 0 0 1 851,853 M851,853 A 500,0.1 0 0 1 146,853" />
    </group>
</vector>


2. 定义动画anim: 

// vector_anim.xml

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
    <objectAnimator
        android:duration="3000"
        android:propertyName="pathData"
        android:valueFrom="M67,750 L500,0 500,0 933,750 67,750        M146,853 A 0.1,500 0 0 1 146,148 M146,148 A 500,0.1 0 0 1 851,148  M851,148 A 0.1,500 0 0 1 851,853 M851,853 A 500,0.1 0 0 1 146,853"
        android:valueTo="M147,853 L147,147 853,147 853,853 147,853    M146,853 A 0.1,500 0 0 1 146,148 M146,148 A 500,0.1 0 0 1 851,148  M851,148 A 0.1,500 0 0 1 851,853 M851,853 A 500,0.1 0 0 1 146,853"
        android:valueType="pathType" />


    <objectAnimator
        android:duration="3000"
        android:propertyName="pathData"
        android:startOffset="3000"
        android:valueFrom="M147,853 L147,147 853,147 853,853 147,853    M147,853 A 0.1,500 0 0 1 147,147 M147,147 A 500,0.1 0 0 1 853,147  M853,147 A 0.1,500 0 0 1 853,853 M851,853 A 500,0.1 0 0 1 147,853"
        android:valueTo="M147,853 L147,147 853,147 853,853 147,853      M147,853 A 500,500 0 0 1 147,147 M147,147 A 500,500 0 0 1 853,147  M853,147 A 500,500 0 0 1 853,853 M853,853 A 500,500 0 0 1 147,853"
        android:valueType="pathType" />
</set>

3. 定义animated-vector

//res/drawable/vector_animation.xml

<?xml version="1.0" encoding="utf-8"?>
<animated-vector xmlns:android="http://schemas.android.com/apk/res/android"
                 android:drawable="@drawable/vector_drawable" >
    <target
            android:name="vector"
            android:animation="@anim/vector_anim" />
    <target
            android:name="rotation"
            android:animation="@anim/vector_rotation" />
</animated-vector>

4. 应用到控件中:

<TextView
    android:id="@+id/vector_anim"
    android:layout_width="200dp"
    android:layout_height="200dp"
    android:background="@drawable/vector_animation"

android:textColor="#88000000" />

public void vector(){ // 点击TextVew时执行此方法
   Drawable drawable = vectorView.getBackground();
   if (drawable instanceof Animatable) {
      ((Animatable) drawable).start();
   }
}

1.9.6. 转场动画Activity transitions

https://developer.android.com/training/material/animations.html#Transitions

n 分类
Explode,  Fade,  Slide,  共享元素

n  转场动画实现步骤(Explode, Fade, Slide):

1. 设置窗口属性,开启此功能

protected void onCreate(Bundle savedInstanceState) {   

   // 第一步: 支持转场切换,注意要放在setContentView()之前
   getWindow().requestFeature(Window.FEATURE_CONTENT_TRANSITIONS);

}

2. 构造Transition对象,设置进入退出动画

Transition transition = new Explode();  // FadeSlide

transition.setDuration(1000);

getWindow().setEnterTransition(transition);    // 启动时的动画
getWindow().setExitTransition(transition);     // 进入其它界面时的动画
getWindow().setReenterTransition(transition);  // 从其它界面返回时的动画
getWindow().setReturnTransition(transition);   // 退出时的动画

3. 开启新的Activity

@TargetApi(Build.VERSION_CODES.LOLLIPOP)
private void startAcitivityWithBundle(Class cls) {
   Intent intent = new Intent(activity, cls);
   ActivityOptions options = ActivityOptions.makeSceneTransitionAnimation(activity);
   startActivity(intent, options.toBundle());
}

4. 在新的Activiy中也添加进窗口的动画效果,同步骤12

protected void onCreate(Bundle savedInstanceState) {
   super.onCreate(savedInstanceState);

   getWindow().requestFeature(Window.FEATURE_CONTENT_TRANSITIONS);

   Transition transition = new Explode();
   transition.setDuration(1000);
   getWindow().setEnterTransition(transition);
   getWindow().setExitTransition(transition);
   getWindow().setReenterTransition(transition);
   getWindow().setReturnTransition(transition);
}

5. 在新的Activity中,使用finishAfterTransition()替代finish()来结束Acitivity

public void onFinish(View view) {
   if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
      finishAfterTransition();
   } else {
      finish();
   }
}

n 带共享元素的转场动画实现(ActivityA启动ActivityB):

第一步:与上面第一步相同

 getWindow().requestFeature(Window.FEATURE_CONTENT_TRANSITIONS);

第二步:禁用Activity窗口的切换动画

getWindow().setEnterTransition(null);
getWindow().setExitTransition(null);
getWindow().setReturnTransition(null);
getWindow().setReenterTransition(null);

第三步:在共享元素中配置transitionName属性

ActivityA中的共享元素配置:

<ImageView

    android:transitionName="share_01"/>

<TextView
    android:transitionName="share_02"/>

ActivityB中的共享元素配置:

<ImageView

    android:transitionName="share_01"/>

<TextView
    android:transitionName="share_02"/>

第四步:

@TargetApi(Build.VERSION_CODES.LOLLIPOP)
private void startAcitivityWithBundle(Class cls) {
       Intent intent = new Intent(this, ShareActivity.class);
      ActivityOptions options = ActivityOptions.makeSceneTransitionAnimation(

            thisivImage"share_01");
//    ActivityOptions options = ActivityOptions.makeSceneTransitionAnimation(this,
//          new Pair(ivImage, "share_01"),
//          new Pair(tvText, "share_02"));
      startActivity(intent, options.toBundle());
}

第五步:在新的ActivityB中,使用finishAfterTransition()替代finish()来结束Acitivity

public void onFinish(View view) {
   if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
      finishAfterTransition();
   } else {
      finish();
   }
}

1.10. 新控件:RecyclerView CardView SwipeRefreshLayout

(1)RecyclerView 可回收视图

l 可以用来实现ListViewGridView、瀑布流,通过复用有限数量的View,来提高滚动时的性能。

l 三种布局管理器:

LinearLayoutManager 列表布局

GridLayoutManager 网格布局

StaggeredGridLayoutManager 瀑布流布局

l 适配器:需要继承RecyclerView.Adapter

l ViewHolder对象:需要继承RecyclerView.ViewHolder

l 没有类似ListViewsetOnItemClickListener方法,

可以通过给item根节点设置点击事件的方式实现;

l Item设置点击事件后,按下时才显示水波纹效果;

(2)CardView 卡片视图

用来实现阴影和圆角效果,是FrameLayout的子类。

cardElevation:设置阴影 (代码实现:setCardElevation)

cardCornerRadius:设置圆角(代码实现:setRadius)

carBackgroundColor: cardview的背景

(3)SwipeRefreshLayout 下拉刷新控件

<android.support.v4.widget.SwipeRefreshLayout
    android:id="@+id/swipe_fresh_layout"
    android:layout_width="match_parent"
    android:layout_height="wrap_content">
    <android.support.v7.widget.RecyclerView
        android:id="@+id/recycler_view"
        android:layout_width="match_parent"
        android:layout_height="match_parent"/>
</android.support.v4.widget.SwipeRefreshLayout>

// 设置下拉刷新控件显示的颜色
swipeRefreshLayout.setColorSchemeResources(...);
// 参数1: 下拉时是否缩放
// 参数2: 下拉时开始显示的位置
// 参数2: 下拉手势结束后,下拉刷新控件显示的位置
swipeRefreshLayout.setProgressViewOffset(false1050);
// 显示下拉刷新控件
swipeRefreshLayout.setRefreshing(true);
// 设置下拉监听事件
swipeRefreshLayout.setOnRefreshListener(...);

1.11. 兼容性

l 兼容性

1)兼容低版本: 调色板(Palette)RecyclerViewCardView

(2)部分兼容低版本: 主题样式

(3)不兼容的功能:

     阴影,轮廓,裁剪,染色,矢量图,全新动画

l 定义不同的资源文件夹,存放不同的文件

res/layout-v21/      item_news.xml   android:translationZ="10dp"

res/layout          item_news.xml   

res/drawable        selector_item.xml普通的选择器

res/drawable-v21    selector_item.xml 水波纹定义

res/values 

res/values-v21

l 使用以上无法兼容低版本的功能时,要进行版本的判断:

@TargetApi(Build.VERSION_CODES.LOLLIPOP)
public void onFinish(View view) {
   finishAfterTransition();
}

public void onFinish(View view) {
   if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
      finishAfterTransition();
   } else {
      finish();
   }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值