安卓 5.0新特性学习

在安卓5.0 的时候加入了触摸反馈,也就是水波纹
使用

1.现在创建新的工程的时候一般默认按钮有水波纹效果,如果想去掉,给view指定一个颜色就没有了

代码:

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

设置水波纹颜色,目前我发现只能通过主题设置,不可以直接写到xml中修改 主题:

<!-- Base application theme. --> 
<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar"> 
<!-- Customize your theme here. -->
<item name="colorPrimary">@color/colorPrimary</item> 
<item name="colorAccent">@color/colorAccent</item>
</style> 

设置水波纹颜色

<item name="colorControlHighlight">@color/colorAccent</item>

选中颜色设置,控件,CheckBox,RadioButton之类的控件

<item name="colorControlHighlight">@color/colorAccent</item>

Button 点击水波纹效果
这里写图片描述


ActivityOptions动画详解

ActivityOptions 是5.0 新出来动画,先来看下效果
原点爆炸
这里写图片描述


点击列表图片,过渡到下个页面动画
这里写图片描述


explode 和slide 动画效果
这里写图片描述


explode : 页面展开效果
slide : 侧滑

  //Gravity.TOP  从上往下滚动
  //Gravity.BOTTOM  从下往上
  //Gravity.LEFT  从左滚动过来

原点爆炸动画学习

原点爆炸动画的实现,主要使用到了,页面之间共享元素,而这个元素通常指view,把A界面的元素传递到B界面,在A界面退出,B界面进来的时候,共享元素就会开始过渡,这个过渡是有动画效果的,而这个元素共享只是原点爆炸的第一步:

看下A 界面 xml布局:

 <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent">

        <TextView
            android:layout_marginTop="10dp"
            android:layout_marginLeft="10dp"
            android:text="圆点爆炸demo"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content" />
        <android.support.design.widget.FloatingActionButton
            android:id="@+id/fb"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_alignParentBottom="true"
            android:layout_alignParentRight="true"
            android:layout_marginBottom="30dp"
            android:layout_marginRight="10dp"
            android:transitionName="@string/fb_sharedelementname"
            android:src="@android:drawable/ic_dialog_email"/>
    </RelativeLayout>

FloatingActionButton在界面的右下角,细心的同学会看到多了一个不认识的标签:

   android:transitionName="@string/fb_sharedelementname"

这个标签就是用来标记共享元素的,A界面的元素,跟B界面的元素都是独立view,用 android:transitionName关联起来,形成元素共享,稍后看B 界面的xml你就懂了。

FloatingActionButton 点击事件,跳转到下一级界面:

     activity = CircularRevealMainActivity.this;
     final FloatingActionButton fb = (FloatingActionButton) findViewById(R.id.fb);
     fb.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
          ActivityOptions activityOptions=ActivityOptions.
          makeSceneTransitionAnimation
          (activity,fb,fb.getTransitionName());

            Intent  intent=new Intent(activity,CircularRevealPaoZaActivity.class);
              activity.startActivity(intent,activityOptions.toBundle());

            }
        });

第一个参数上下文,第二个参数共享view,第三个参数共享元素的名字

ActivityOptions. makeSceneTransitionAnimation (activity,fb,fb.getTransitionName());

ActivityOptions 这个类只能兼容到5.0,低版本运行会奔溃,如果你兼容到低版本需要做版本控制:

      if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
         //5.0 以上执行
        } else {
          //低版本执行
        }

每次需要做版本控制,很烦,刚好有一个兼容类ActivityOptionsCompat,此类能兼容到4.x,动画都能出现,那么这个类就可以用了,我注意了下,目前主流APP,qq,今日头条,基本上只兼容到4.0左右,也就是说低版本不需要适配动画了,而且ActivityOptions 的动画效果ActivityOptionsCompat都有,只是在跳转的时候小小的改变

例:共享元素跳转方法,只要替换成这样,其他不改变

ActivityOptionsCompat options5 = ActivityOptionsCompat.makeSceneTransitionAnimation(MainActivity.this, iv, "options5");
ActivityCompat.startActivity(context, new Intent(context, Activity_A.class), options5.toBundle());

接下来讲FloatingActionButton 触发点击事件跳到下一界面

B界面xml:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:id="@+id/main_rl"
    android:background="@android:color/transparent"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <android.support.design.widget.FloatingActionButton
        android:id="@+id/shared_fb"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerInParent="true"
        app:elevation="0dp"
        app:fabSize="normal"
        android:background="@color/colorAccent"
        app:pressedTranslationZ="8dp"
        android:transitionName="@string/fb_sharedelementname" />

    <RelativeLayout
        android:id="@+id/context_rl"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:visibility="invisible"
        android:background="@color/colorAccent"
        tools:visibility="visible">

        <TextView
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:layout_centerInParent="true"
            android:gravity="center"
            android:text="内容中心"
            android:textSize="30dp" />
    </RelativeLayout>
</RelativeLayout>

先讲下 FloatingActionButton ,在布局中为什么这么写

 <android.support.design.widget.FloatingActionButton
        android:id="@+id/shared_fb"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerInParent="true"
        app:elevation="0dp"
        app:fabSize="normal"
        android:background="@color/colorAccent"
        app:pressedTranslationZ="8dp"
        android:transitionName="@string/fb_sharedelementname" />
  1. android:transitionName=”@string/fb_sharedelementname” 给view设置共享标记,这一个要设置的
  2. app:elevation=”0dp” 为什么写这个,FloatingActionButton 不会因为自己被下一个view覆盖,他会永远浮在rootview的最上层。
  3. FloatingActionButton 定位到布局中间

做完这个操作我们就可以看到这样的动画效果:

这里写图片描述

在之前的效果图片上我们看到,他有一个微微弯曲的效果,不知道你们注意没

 //这段就是给共享元素设置了一个动画过渡
        Transition  transition= TransitionInflater.from(this).inflateTransition(R.transition.arc_motion);
        getWindow().setSharedElementEnterTransition(transition);
        transition.addListener(new Transition.TransitionListener() {
            @Override
            public void onTransitionStart(Transition transition) {

            }

            @Override
            public void onTransitionEnd(Transition transition) {
                transition.removeListener(this);
                //共享元素过渡动画执行完毕后,开始执行爆炸动画效果
               showCircularReveal();
            }

            @Override
            public void onTransitionCancel(Transition transition) {

            }

            @Override
            public void onTransitionPause(Transition transition) {

            }

            @Override
            public void onTransitionResume(Transition transition) {

            }
        });

这段代码的作用就是给共享元素加入一个微微弯曲的动画

 Transition  transition= TransitionInflater.from(this).
 inflateTransition(R.transition.arc_motion);
        getWindow().setSharedElementEnterTransition(transition);

arc_motion 布局

<?xml version="1.0" encoding="utf-8"?>
<transitionSet
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:duration="500"
    android:interpolator="@android:interpolator/linear_out_slow_in">

    <changeBounds>
        <!--suppress AndroidElementNotAllowed -->
        <arcMotion
            android:maximumAngle="90"
            android:minimumHorizontalAngle="90"
            android:minimumVerticalAngle="0"/>
    </changeBounds>
</transitionSet>

showCircularReveal(); 用来显示爆炸圆的动画

  private void showCircularReveal() {
        int cx = (main_rl.getLeft() + main_rl.getRight()) / 2;
        int cy = (main_rl.getTop() + main_rl.getBottom()) / 2;

        float finalRadius = (float) Math.hypot(main_rl.getWidth(), main_rl.getHeight());

        // 设置圆形显示动画
        //第一个参数就是执行动画的view;第二,第三个参数就是执行动员的x,y轴距离;第四个参数动画起始大                     //小半径;第五个参数动画最大执行半径
        Animator anim = ViewAnimationUtils.createCircularReveal(main_rl, cx, cy, shared_fb.getWidth()/2, finalRadius);
        anim.setDuration(300);
        anim.setInterpolator(new AccelerateDecelerateInterpolator());
        anim.addListener(new AnimatorListenerAdapter() {
            @Override
            public void onAnimationEnd(Animator animation) {
                super.onAnimationEnd(animation);
                main_rl.setVisibility(View.VISIBLE);
                setInitAnimation();
            }

            @Override
            public void onAnimationStart(Animator animation) {
                super.onAnimationStart(animation);
                main_rl.setBackgroundColor(ContextCompat.getColor(activity, R.color.colorAccent));
            }
        });
        anim.start();
    }
  1. ViewAnimationUtils.createCircularReveal() 5.0的新特性
  2. xml 布局中最外层view,用来获取界面的中心点
     int cx = (main_rl.getLeft() + main_rl.getRight()) / 2;
     int cy = (main_rl.getTop() + main_rl.getBottom()) / 2;
  1. 获取界面的对角线
      float finalRadius = (float) Math.hypot(main_rl.getWidth(), main_rl.getHeight());

爆炸动画执行完毕后,执行下面这个方法,让context_rl 显示,在布局中是占位存在,覆盖掉布局中的
FloatingActionButton。

    public  void   setInitAnimation()
    {
        Animation animation = AnimationUtils.loadAnimation(this, android.R.anim.fade_in);
        animation.setDuration(300);
        context_rl.startAnimation(animation);
        context_rl.setVisibility(View.VISIBLE);
    }

不可以在控制FloatingActionButton 的时候setVisibility()控制隐藏 ,
最好的办法就是,布局覆盖。

由于没有给 B Activity 设置 销毁动画( ReturnTransition),所以在退出B Activity的时候,动画会自动翻转执行。

设置了ReturnTransition ,点击back按钮会执行这个动画

 Fade fade = new Fade();
 getWindow().setReturnTransition(fade);
 fade.setDuration(300);

explode 和slide 动画学习

explode , getWindow().setExitTransition(explode);设置退出activity 过渡动画

A activity

展开动画

   /**
     * 设置窗口  离开动画
     * <p>
     * 测试证明  这个方法在这个Activity 跳转之前设置都有效果
     */
    public void setWindsExitAnimations() {
        Explode explode = new Explode();
        explode.setDuration(500);
        getWindow().setExitTransition(explode);
    }

跳转

ActivityOptions options = ActivityOptions.makeSceneTransitionAnimation
 (ActivityOptionsAnimationSetActivity.this);
                activity.startActivity(new Intent(ActivityOptionsAnimationSetActivity.this, ExplodeActivity.class), options.toBundle());

B activity
渐变动画

   private void setWindsEnterAnimations() {
        Fade   slide=new Fade();
        slide.setDuration(300);
        getWindow().setEnterTransition(slide);
    }

slide
slide 侧滑动画

A activity


    private void setWindsSlideExitAnimations() {

        //Gravity.TOP  从上往下滚动
        //Gravity.BOTTOM  从下往上
        //Gravity.LEFT  从左滚动过来
        Slide slide = new Slide(Gravity.LEFT);
        slide.setDuration(500);
        slide.setInterpolator(new AccelerateDecelerateInterpolator());
        getWindow().setExitTransition(slide);
    }

跳转

ActivityOptions options1 = ActivityOptions.makeSceneTransitionAnimation
(ActivityOptionsAnimationSetActivity.this);
                activity.startActivity(new Intent(ActivityOptionsAnimationSetActivity.this, SlideActivity.class), options1.toBundle());

B activity

Fade slide=new Fade();
slide.setDuration(300);
getWindow().setEnterTransition(slide);

Fade ,slide,explode 也可以用xml建立

<?xml version="1.0" encoding="utf-8"?>
<slide xmlns:android="http://schemas.android.com/apk/res/"
    android:duration="1000"/>
 Slide slide = TransitionInflater.from(this).inflateTransition(R.transition.activity_slide);
 getWindow().setExitTransition(slide);

在写Slide ,explode demo的时候,A 界面进入B 界面,B界面按返回键,操作过快情况下返回A 界面,就会出现空白,或者view 缺少

我这样处理还是不行,还是会出现空白,这就坑了,不过我知道一个解决方法


    @Override
    public boolean onKeyDown(int keyCode, KeyEvent event) {
        if(keyCode == KeyEvent.KEYCODE_BACK) {
            finishAfterTransition();//退出动画一定要这么写,要不然会出现bug
            return false;
        }
            return super.onKeyDown(keyCode, event);
    }

解决方法:
这样处理就不会出现,我也不知道这样处理是不是对的

    @Override
    public void onBackPressed() {
        super.onBackPressed();
        finish();
    }

  • Exit Transition:可以理解为activity进入后台的过渡动画
  • Enter Transition:可以理解为创建activity并显示时的过渡动画
  • Return Transition:可以理解为销毁activity时的过渡动画
  • Reenter Transition:可以理解为activity从后台进入前台时的过渡动画

View的高度与阴影

View高度 = elevation + translationZ
  • elevation表示view的高度,高度越大,阴影越大,可以在xml中直接使用属性, 也可以在代码中使用view.setEvelvation();
android:elevation="10dp"
  • transtionZ属性表示view在Z方向移动的距离,一般用于属性动画中
android:translationZ="10dp"

  • 高度影响View的绘制顺序,过去是按View添加顺序绘制,先添加的先绘制,现在高度小的先绘制,因为高度小的,层级低,在下面, 高度相同的,按添加顺序绘制

注意:
如果View的背景色为透明,则不会显示出阴影效果
只有子View的大小比父View小时,阴影才能显示出来


git地址:https://github.com/Followk/demoanimation


参考大神:
Transition 动画参考
http://blog.csdn.net/caroline_wendy/article/details/50756717
http://blog.csdn.net/ss1168805219/article/details/53445063
https://damonzh.github.io/2016/04/04/transition-framework/
http://blog.csdn.net/qq_23547831/article/details/51821159
http://blog.csdn.net/tm1989tm/article/details/51025309

5.0新特性参考:
http://blog.csdn.net/tianzhu2725/article/details/52775285
http://blog.csdn.net/yangxi_pekin/article/details/50610818
http://blog.csdn.net/a396901990/article/details/40187203

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值