Android5.0新特性

虽然6.0早就出了,但是呢,5.0用的都很少。

主要就是更换版本

较高,用户强烈要求才会更换。

Android5.0新特性_第1张图片

Android 5.0新特性

  1. Material Theme
  2. View的阴影和裁剪
  3. Drawables图形资源
  4. Animations
  5. 新增控件-卡片和列表

http://developer.android.com/training/material/index.html

1.MaterialDesigh概述

材质设计,以抽象化的形式展现物理世界的特征。

Material 主题

  • 系统自带的主题

    1. @android:style/Theme.Material
    2. @android:style/Theme.Material.Light
    3. @android:style/Theme.Material.Light.DarkActionBar
  • 如何自定义主题

    参见http://developer.android.com/training/material/theme.html

    不同的Theme,不同的属性值。

  • 常用的样式属性

     
    

2.阴影和裁剪

Z轴属性

  • Z = elevation + translationZ

    android:elevation   //静态Z轴的高度。相对于父控件的高度
    android:translationZ    //Z轴偏移的高度。
    
  • 高度决定了View的遮盖关系,遮盖关系决定绘制时机。

阴影轮廓

android:outlineProvider:
none:不显示阴影
background :按照显示区域来绘制阴影
bounds :在View的边界描绘阴影
paddedBounds: 在View边界描绘阴影,但会忽略paddingTop和paddingLeft

View都是矩形的,阴影默认是沿着背景的边界绘制。如果背景是矩形了自然没有问题。 如果是圆形的,分两种情况:

  1. 通过shape定义的,系统可以识别出真实边界,阴影绘制没有问题.
  2. 带有透明通道的png图片,会当成矩形绘制阴影。因为系统无法排除透明通道,识别出真实的边界,

为了避免圆形的View显示矩形的阴影,,View增加了一个新的描述来指明内容显示的形状,这就是轮廓。

  • 布局设置:

    android:outlineProvider="none|background|bounds|paddedBounds" 
    
    none 不显示阴影
    background :按照显示区域来绘制阴影
    bounds :在View的边界描绘阴影
    paddedBounds: 在View边界描绘阴影,但会计算paddingTop和paddingLeft
    
  • 代码设置:

    圆形png图片因为无法排除透明通道,无法识别出真实边界,所以可以自定义,代码提供轮廓

    View.setOutlineProvider(new ViewOutlineProvide(){
         public void getOutline(View view, Outline outline) {
            //矩形,圆形,圆角矩形,Path。除了正常的阴影,也可以自定义奇葩的阴影效果
             outline.setOval(0, 0, view.getWidth(), view.getHeight());
        }
    });
    

轮廓裁剪

由于轮廓可以自定义,当轮廓小于View的大小,View并不会变小。如果希望View大小跟轮廓匹配,可以裁剪View的大小以适应轮廓,这样也可以通过裁剪生成新的形状。

Outline.canClip();//是否可以被裁剪。目前支持矩形,圆形,圆角矩形
View.setClipToOutline(true);//允许裁剪View大小以适应轮廓
  • 只能往小了裁,不能往大了裁。
  • 轮廓大小如果大于View大小,只会扩大阴影的绘制路径,但不会超出父控件边界
  • 裁剪的本质是绘制时裁剪画布的大小,但不会改变View的测量大小,触摸区域。

3. Drawables图形资源

  • Drawable渲染
  • 矢量图
  • 色彩提取

色彩渲染

  • 如何设置

    代码:
        Drawable#setTint(int color);//设置渲染色
        Drawable#setTintMode(PorterDuff.Mode tintMode);//设置渲染模式
    xml文件:
        //可以应用xml定义的bitmap或者ImageView或者View的background等涉及到drawable的地方.
        android:tint
        android:tintMode
    
  • 渲染模式

    PorterDuff.Mode 18种模式,其决定了原图颜色和渲染颜色的取舍和合成规则。

    原理:将原图颜色Dst与渲染颜色Src每个像素点的alpha和color值通过算法计算得到新的颜色,以实现不同的混合效果。

    效果参见ApiDemos-Graphics-Xfermodes.演示了16种效果

矢量图

    
        

取色器

  • android.support.v7.graphics.Palette

    Vibrant 鲜艳的
    Vibrant dark鲜艳的暗色
    Vibrant light鲜艳的亮色
    Muted 柔和的
    Muted dark柔和的暗色
    Muted light柔和的亮色
    
    //在子线程可以使用同步操作
     Palette p = Palette.from(bitmap).generate();
    
     //在主线程使用异步操作
     Palette.from(bitmap).generate(new PaletteAsyncListener() {
         public void onGenerated(Palette p) {
             // Use generated instance
    
         }
     });
    
    
    //gradle 添加依赖
    dependencies {  
        ...
        compile 'com.android.support:palette-v7:21.0.0'
    }
    
  • 其他

    //获取某个像素点的颜色值
    int color=Bitmap.getPixel(int x, int y);
    

3.Animations

  • Touch feedback 触摸反馈
  • Circular Reveal 循环揭露
  • Activity transitions
  • Curved motion
  • View state changes

涟漪效果RippleDrawable

  • Button自带涟漪动画

    1. 默认效果,有背景,按下带水波纹效果
    2. android:background="?android:selectableItemBackground";无背景,按下有水波纹效果
    3. android:background="?android:selectableItemBackgroundBorderless";无背景,V控件大小不限制水波纹的扩散
  • 自定义涟漪背景:

    
    
    
        
        
    
    

圆形缩放动画 RevealAnimator

可用于View的隐藏显示的过渡

 /**
 * @param view 要执行动画的View
 * @param centerX 圆心X
 * @param centerY 圆心Y
 * @param startRadius 开始半径
 * @param endRadius 结束半径
 */
ViewAnimationUtils.createCircularReveal(myView, cx, cy, 0, finalRadius);

状态切换动画

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

  • StateListAnimator
  • AnimatedStateListDrawable
  • StateListAnimator 属性动画

    • 定义
      
          //切换到按下状态时执行的动画
        
          
            
              
              //同时还可以执行其他的动画
          
        
          //切换默认状态时执行的动画
        
          
            
          
        
      
      
    • 使用

      xml布局:
      android:stateListAnimator属性设置
      代码:
      View#setStateListAnimator(AnimatorInflater.loadStateListAnimator(this,R.drawable.selector_anim_state));
      
    • 其他

      如果设置了Material Theme,Button默认会有Z轴改变的动画效果。如果想屏蔽,可以设置android:stateListAnimator为 @null

  • AnimatedStateListDrawable 过渡帧动画

    • 定义

      
      
          
          
           
          
      
          
          
              
                  //定义每一帧的图片资源
                  
                  
                  ...
              
          
          ...
      
      
    • 如何使用

      android:background当成普通drawable使用

矢量图动画 AnimatedVectorDrawable

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

  1. 在drawable目录定义一个矢量图

    
    vector xmlns:android="http://schemas.android.com/apk/res/android"
    android:height="64dp"
    android:width="64dp"
    android:viewportHeight="600"
    android:viewportWidth="600">
        
            
        
    
    
  2. 在drawable目录定义一个矢量图动画

    
    
        
        
    
    
  3. 在anim目录定义要执行的属性动画

    
    
    
    
    
        
    //pathData要求参数个数相同,命令也要相同。
    
    
  4. 使用矢量图动画

    animvectordrawable.xml作为background设置给View
    
    //代码中获取到background,因为是特殊的background,播放
    Drawable drawable = vector.getBackground();
    if (drawable instanceof Animatable) {
       ((Animatable) drawable).start();
    }
    

曲线运动

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

  • PathInterpolator

    通过Path定义动画插入器的运动轨迹.二阶,三阶贝塞尔曲线和自定义Path

    动画插入器:通过运动曲线模型干预动画的执行。
    运动曲线模型:一个 1x1 的正方形内指定一个运动曲线,起点位于 (0,0),终点 (1,1),控制点形成运动曲线 //二阶贝塞尔曲线 public PathInterpolator(float controlX, float controlY) //三阶贝塞尔曲线 public PathInterpolator(float controlX1, float controlY1, float controlX2, float controlY2) //Path定义运动曲线 public PathInterpolator(Path path) Path path = new Path(); path.lineTo(0.4f, 0.8f); path.lineTo(0.6f, 0.0f); path.lineTo(1f, 1f);//必须从0,0开始,1,1结束 PathInterpolator pathin=new PathInterpolator(path);
  • ObjectAnimator 属性动画可以通过Path设置View的带X,Y属性

    Path path2 = new Path();
    path2.lineTo(40, 80);
    path2.lineTo(50, 40);
    ObjectAnimator.ofFloat(mAnimView,View.TRANSLATION_X,View.TRANSLATION_Y,path2).setDuration(2000).start();
    

注意:Tween动画跟属性动画做动画,Tween动画不该变View真实的位置及大小,属性动画改变真实位置及大小。

Activity转场动画

回顾Activity切换动画

新增Activity元素场景转换动画 - 进入、退出、共享元素转换

  • 回顾Activity切换动画

    代码:
        //Activity切换动画。api 16以后出现了更好的选择--ActivityOption
        public void overridePendingTransition(int enterAnim, int exitAnim);//在startActivity之后,finish之前执行,配置进来的和出去的Activity执行的动画
    主题:
        //主题配置切换动画
        
          
        
    
  • Activity元素场景转换动画

    • 分类

      1. 进入退出--Visibility

        Explode分解 - 从场景中心移入或移出视图。
        Slide滑动 - 从场景边缘移入或移出视图。
        Fade淡入淡出 - 通过调整透明度从场景增添或移除视图
        可实现接口进行自定义

      2. 共享元素动画-- Transition

        changeBounds - 为目标视图的布局边界的变化添加动画。
        changeClipBounds - 为目标视图的裁剪边界的变化添加动画。
        changeTransform - 为目标视图的缩放与旋转变化添加动画。
        changeScroll - 为目标视图的ScrollTo操作添加动画。
        changeImageTransform - 为目标图像的大小与缩放变化添加动画。

    • 如何使用

      1. 通过Theme定义
          
      
          Activity里代码设置:
      
          / 允许使用transitions
          getWindow().requestFeature(Window.FEATURE_CONTENT_TRANSITIONS);
          // 指定进入、退出、返回、重新进入时的transitions
          TransitionSet set = new TransitionSet();//也可设置TransitionSet
          set.addTransition(new Explode());
          set.addTransition(new Fade());
          getWindow().setEnterTransition(new Explode());
          getWindow().setExitTransition(new Explode());
          getWindow().setEnterTransition(new Explode());
          getWindow().setExitTransition(new Explode());
          // 指定进入、退出、返回、重新进入时的共享transitions
          getWindow().setSharedElementEnterTransition(new ChangeTransform());
          getWindow().setSharedElementExitTransition(new ChangeTransform());
          getWindow().setSharedElementReturnTransition(new ChangeTransform());
          getWindow().setSharedElementReenterTransition(new ChangeTransform());
      
      2. 启动Activity
          //没有共享元素
          ActivityOptions options=ActivityOptions.makeSceneTransitionAnimation(this);
          //1个共享元素
          ActivityOptions options = ActivityOptions
          .makeSceneTransitionAnimation(this, sharedElementView, "sharedElementName");
          //多个共享元素
          ActivityOptions options = ActivityOptions.makeSceneTransitionAnimation(this,
          Pair.create(sharedElementView1, "sharedElementName1"),
          Pair.create(sharedElementView2, "sharedElementName2"));
          // 启动Activity
          startActivity(new Intent(getApplicationContext(), XXXActivity.class), options.toBundle());
      
          共享元素:利用 android:transitionName 属性对两个布局中的共享元素指定一个通用名称sharedElementName,以便过渡动画的执行
      
      3. 关闭Activity
          调用finishAfterTransition替代finish。返回键默认处理为finishAfterTransition
      

RecyclerView

  • 介绍

    • RecyclerView = 灵活的的listview,可实现网格、瀑布流等效果
  • 基本功能三要素

    • RecyclerView
    • LayoutManagers
    • Adapter
  • 显示数据集

参见 https://developer.android.com/training/material/lists-cards.html#RecyclerView

1. 在布局文件中使用RecyclerView
2. 在Activity中找到RecyclerView
3. RecyclerView.setLayoutManager(LayoutManager)
4. RecyclerView.setAdapter(Adapter)
5. 定义Adapter
~~~java
public class MyAdapter extends RecyclerView.Adapter {
    private final List> data;
    public MyAdapter(List> data) {
        this.data = data;
    }
    @Override
    public int getItemCount() {
        return data == null ? 0 : data.size();
    }
    @Override
    public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        SimpleVH svh = new SimpleVH(View.inflate(parent.getContext(), R.layout.item_simple, null));
        return svh;
    }
    @Override
    public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
        SimpleVH svh = (SimpleVH) holder;
        svh.iv.setImageResource(data.get(position).second);
        svh.name.setText(data.get(position).first);
        svh.item.setText("position: " + position );

    }
    public static class SimpleVH extends RecyclerView.ViewHolder {
        ImageView iv;
        TextView name;
        TextView item;

        public SimpleVH(View itemView) {
            super(itemView);
            iv = (ImageView) itemView.findViewById(R.id.iv);
            name = (TextView) itemView.findViewById(R.id.name);
            item = (TextView) itemView.findViewById(R.id.item);
        }
    }
}
~~~
  • 显示网格布局及瀑布流布局

实质上就是设置不同的LayoutManager

~~~ java
- LinearLayoutManager(Context context, 
                    int orientation,  // 布局方向
                    boolean reverseLayout //是否反转
                    )
- GridLayoutManager(Context context,
                    int spanCount,  // 几列
                    int orientation, // 方向
                    boolean reverseLayout //是否反转
                    )
- StaggeredGridLayoutManager(
                    int spanCount, // 几列
                    int orientation // 方向
                    )
~~~
  • 设置点击事件

    1. RecyclerView.addOnItemTouchListener

    使用了比较底层的API,较为复杂

    1. 通过Adapter将点击事件传递出来

    使用回调的设计手法

    ~~~java
    /**adapter*/
    public static interface OnItemClickListener {
        public void onItemClick(RecyclerView.ViewHolder vh);
    }
    public void setOnItemClickListener(OnItemClickListener oicl) {
        this.oicl = oicl;
    }
    private void onItemClick(RecyclerView.ViewHolder vh) {
        if (oicl != null) {
            oicl.onItemClick(vh);
        }
    }
    @Override
    public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
        //...
        svh.itemView.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                // 通知同一个方法,
                onItemClick(holder);
            }
        });
    }
    
    /**Activity*/
    myAdapter.setOnItemClickListener(new MyAdapter.OnItemClickListener() {
        @Override
        public void onItemClick(RecyclerView.ViewHolder vh) {
            Toast.makeText(NewWidgetActivity.this, "position: "+ vh.getAdapterPosition(),Toast.LENGTH_SHORT).show();
        }
    });
    ~~~
    
  • 下拉刷新

    • 借助android.support.v4.widget.SwipeRefreshLayout
    • 使用方法

      1. 用SwipeRefreshLayout作为RecyclerView的父控件
      2. SwipeRefreshLayout.setOnRefreshListener
      3. 在OnRefreshListener完成数据的获取,然后调用SwipeRefreshLayout.setRefreshing(fasle)
      4. 个性化

        //定制SwipeRefreshLayout的样式
        //设置箭头的颜色
        swipeRefreshLayout.setColorSchemeColors(Color.RED,Color.GREEN, Color.BLUE);
        //设置圆圈的背景 v7 22以后
        swipeRefreshLayout.setProgressBackgroundColorSchemeColor(Color.GRAY);
        

CardView

  • android.support.v7.widget.CardView
  • 使用方法

    1. 在布局中使用android.support.v7.widget.CardView
    2. 添加属性 ~~~xml CardView常用属性: cardview:cardElevation  卡片高度 cardview:cardMaxElevation  卡片的最大高度 card_view:cardBackgroundColor  卡片的背景色 cardview:cardCornerRadius  卡片的圆角大小 cardview:contentPadding

     卡片内容于边距的间隔 cardview:contentPaddingBottom cardview:contentPaddingTop cardview:contentPaddingLeft cardview:contentPaddingRight cardview:contentPaddingStart cardview:contentPaddingEnd

    cardview:cardUseCompatPadding  设置内边距,V21+的版本和之前的版本仍旧具有一样的计算方式 cardview:cardPreventConrerOverlap  在V20和之前的版本中添加内边距,这个属性为了防止内容和边角的重叠

    ~~~

与旧版本兼容

  • 定义不同的布局

    将使用了新的API的布局放在res/layout-v21/; 其他的放在res/layout/中

  • 主题定义

    1. 继承Theme.AppCompat
    2. 定义颜色的时候去掉android:的命名空间(针对于新的那一些)

    小窍门,所有没有见过的,都去掉,aapt会报错,根据aapt的提示添加android的命名空间

  • 可以通过兼容包使用的效果
    1. RecyclerView
    2. CardView
    3. Palette
  • 不能在21之前版本使用的效果
    1. Activity transitions
    2. Touch feedback
    3. Reveal animations
    4. Path-based animations
    5. Vector drawables
    6. Drawable tinting
  • 代码要判断运行的环境,使用合适的效果

你可能感兴趣的:(Android5.0新特性)