(三十九)MaterialDesign 动画

版权声明:本文为博主原创文章,未经博主允许不得转载。

本文纯个人学习笔记,由于水平有限,难免有所出错,有发现的可以交流一下。

一·、概述

安卓在 5.0 之后添加了 MaterialDesign 动画,主要有以下几种:

Touch feedback(触摸反馈)

Reveal effect(揭露效果)

Activity transitions(Activity 转换效果)

Curved motion(曲线运动)

View state changes (视图状态改变)

Animate Vector Drawables(可绘矢量动画)

二、触摸反馈

触摸反馈是在使用 MaterialDesign 主题的时候,点击按钮会有一个水波纹的扩散效果。

效果1

    <Button
        android:layout_width="match_parent"
        android:minHeight="80dp"
        android:gravity="center"
        android:layout_height="wrap_content"
        android:text="动画!" />

效果:
这里写图片描述

在这里什么都没有进行设置,只是 Activity 继承于 AppCompatActivity,则布局中的 Button 会被替换为 AppCompatButton。

效果2

    <Button
        android:layout_width="match_parent"
        android:minHeight="80dp"
        android:gravity="center"
        android:layout_height="wrap_content"
        android:layout_marginTop="20dp"
        android:background="?android:attr/selectableItemBackground"
        android:text="动画!" />

效果:
这里写图片描述

设置属性 android:background=”?android:attr/selectableItemBackground”。

效果3

    <Button
        android:layout_width="match_parent"
        android:minHeight="80dp"
        android:gravity="center"
        android:layout_height="wrap_content"
        android:layout_marginTop="20dp"
        android:background="?android:attr/selectableItemBackgroundBorderless"
        android:text="动画!" />

效果:
这里写图片描述

设置属性 android:background=”?android:attr/selectableItemBackgroundBorderless”,水波纹变成圆形的,超出了原本按钮的大小。

效果4

    <Button
        android:layout_width="match_parent"
        android:minHeight="80dp"
        android:gravity="center"
        android:layout_height="wrap_content"
        android:layout_marginTop="20dp"
        android:background="@drawable/btn"
        android:text="动画!" />

btn.xml:

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

</ripple>

效果:
这里写图片描述

通过设置 xml,可以修改背景颜色。

效果5

    <Button
        android:layout_width="match_parent"
        android:minHeight="80dp"
        android:gravity="center"
        android:layout_height="wrap_content"
        android:layout_marginTop="20dp"
        android:background="@drawable/btn1"
        android:text="动画!" />

btn1.xml:

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

效果:
这里写图片描述

在 xml 中添加一个图片,这时候执行动画的效果就是图片大小。

效果6

    <Button
        android:layout_width="match_parent"
        android:minHeight="80dp"
        android:gravity="center"
        android:layout_height="wrap_content"
        android:layout_marginTop="20dp"
        android:background="@drawable/btn2"
        android:text="动画!" />

btn2.xml:

<?xml version="1.0" encoding="utf-8"?>
<ripple xmlns:android="http://schemas.android.com/apk/res/android"
    android:color="@color/colorPrimaryDark">
    <item android:id="@android:id/mask" android:drawable="@drawable/ic_launcher"/>
</ripple>

效果:
这里写图片描述

在 xml 中添加 android:id=”@android:id/mask”,图片首先是不会出现的,点击之后才会出现。

三、揭露效果

    <TextView
        android:id="@+id/text_content"
        android:layout_width="match_parent"
        android:layout_height="100dp"
        android:text="揭露效果"
        android:gravity="center"
        android:clickable="true"
        />

MainActivity :

public class MainActivity extends AppCompatActivity {

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

        final TextView textView = ( TextView) findViewById(R.id.text_content);
        textView.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                Animator animator = ViewAnimationUtils.createCircularReveal(textView,
                        textView.getWidth() / 2, textView.getHeight() / 2,
                        0, textView.getWidth());
                animator.setDuration(3000);
                animator.start();
            }
        });
    }
}

效果:
这里写图片描述

代码非常简单,就是通过 createCircularReveal 方法来创建一个动画对象。

public static Animator createCircularReveal(View view,
        int centerX,  int centerY, float startRadius, float endRadius) {
    return new RevealAnimator(view, centerX, centerY, startRadius, endRadius);
}
view 操作的视图
centerX 动画开始的中心点X
centerY 动画开始的中心点Y
startRadius 动画开始半径
startRadius 动画结束半径

四、Activity 转换效果

我们原先使用转场动画的时候是直接进行设置:

overridePendingTransition(android.R.anim.slide_in_left,android.R.anim.slide_out_right);

这种方式效果比较单一,在安卓 5.0 之后退出了一个 ActivityOptions,专门进行转场动画的制作,同时有个对应的兼容包 ActivityOptionsCompat,这个可以兼容到 2.3。

1.普通动画

普通动画有三种:

explode:从场景的中心移入或移出

slide:从场景的边缘移入或移出

fade:调整透明度产生渐变效果

style.xml:

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

        <!--是否覆盖执行,其实可以理解成是否同步执行还是顺序执行-->
        <item name="android:windowAllowEnterTransitionOverlap">true</item>
        <item name="android:windowAllowReturnTransitionOverlap">true</item>
        <!-- 指定进入和退出transitions -->
        <item name="android:windowEnterTransition">@android:transition/explode</item>
        <item name="android:windowExitTransition">@android:transition/explode</item>
    </style>

</resources>

Activity 的跳转使用 ActivityOptionsCompat 方式进行。

        ActivityOptionsCompat comapt= ActivityOptionsCompat.makeSceneTransitionAnimation(this);
        ActivityCompat.startActivity(this,new Intent(this,SecondActivity.class),comapt.toBundle());

效果:
这里写图片描述

修改进入退出样式为 slide。

style.xml:

        <!-- 指定进入和退出transitions -->
        <item name="android:windowEnterTransition">@android:transition/slide_bottom</item>
        <item name="android:windowExitTransition">@android:transition/slide_bottom</item>

效果:
这里写图片描述

修改进入退出样式为 fade。
style.xml:

        <!-- 指定进入和退出transitions -->
        <item name="android:windowEnterTransition">@android:transition/fade</item>
        <item name="android:windowExitTransition">@android:transition/fade</item>

效果:
这里写图片描述

这是普通的进入和突出动画,也可以在代码中进行设置。

    Explode explode = (Explode)TransitionInflater.from(this).inflateTransition(R.transition.explode);
    getWindow().setEnterTransition(explode);

    Slide slide = new Slide(Gravity.BOTTOM);
    slide.setDuration(1000L);
    getWindow().setEnterTransition(slide);

    Fade fade = new Fade();
    fade.setDuration(1000L);
    getWindow().setEnterTransition(fade);

2.共享元素

1.单个共享元素

MainActivity:

public class MainActivity extends AppCompatActivity {

    View imageView;

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

        //设置标志位,允许转场动画
        getWindow().requestFeature(Window.FEATURE_CONTENT_TRANSITIONS);
        setContentView(R.layout.activity_main);

        imageView = (ImageView) findViewById(R.id.img);

    }

    public void click(View view) {
        ActivityOptionsCompat comapt= ActivityOptionsCompat.
                makeSceneTransitionAnimation(this, imageView, getString(R.string.app_name));
ActivityOptionsCompat.makeSceneTransitionAnimation(this, img1, img2);
        //跳转
        ActivityCompat.startActivity(this,new Intent(this,SecondActivity.class),comapt.toBundle());
    }
}

使用 ActivityOptionsCompat 进行转场动画的启动。要使用转场动画,需要在 Activity 中进行设置标志位,或者在 style.xml 中进行设置。

getWindow().requestFeature(Window.FEATURE_CONTENT_TRANSITIONS);

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

activity_main.xml:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical" android:layout_width="match_parent"
    android:layout_height="match_parent">
    <Button
        android:layout_width="match_parent"
        android:layout_height="50dp"
        android:onClick="click"
        android:text="跳转"
        />

    <ImageView
        android:id="@+id/img"
        android:layout_width="50dp"
        android:layout_height="50dp"
        android:src="@drawable/a"
        android:transitionName="@string/app_name"
        />

</LinearLayout>

通过 android:transitionName 设置共享元素,从而实现转场动画。

SecondActivity :

public class SecondActivity extends AppCompatActivity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_second);

    }
}

activity_second.xml:

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

    <ImageView
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:src="@drawable/a"
        android:scaleType="centerCrop"
        android:layout_weight="1"
        android:transitionName="@string/app_name"
        />
</LinearLayout>

在第二个布局中的 ImageView 设置与第一个布局文件中相同的 android:transitionName,表示同一个转场元素。

效果:
这里写图片描述

2.多个共享元素

MainActivity 的 click:

    public void click(View view) {
        Pair<View, String> img1 = Pair.create(imageView, getString(R.string.app_name));
        Pair<View, String> img2 = Pair.create(imageView2, getString(R.string.app));
        ActivityOptionsCompat comapt= ActivityOptionsCompat.makeSceneTransitionAnimation(this, img1, img2);
        //跳转
        ActivityCompat.startActivity(this,new Intent(this,SecondActivity.class),comapt.toBundle());
    }

效果:
这里写图片描述

3.自定义共享元素转换

changeBounds -  改变目标视图的布局边界

changeClipBounds - 裁剪目标视图边界

changeTransform - 改变目标视图的缩放比例和旋转角度

changeImageTransform - 改变目标图片的大小和缩放比例

style.xml:

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

        <!--是否覆盖执行,其实可以理解成是否同步执行还是顺序执行-->
        <item name="android:windowAllowEnterTransitionOverlap">true</item>
        <item name="android:windowAllowReturnTransitionOverlap">true</item>
        <!-- 指定进入和退出transitions -->
        <item name="android:windowEnterTransition">@android:transition/slide_bottom</item>
        <item name="android:windowExitTransition">@android:transition/slide_bottom</item>
        <!-- 指定shared element transitions -->
        <item name="android:windowSharedElementEnterTransition">@transition/enter</item>
        <item name="android:windowSharedElementExitTransition">@transition/enter</item>
    </style>
</resources>

enter.xml:

<?xml version="1.0" encoding="utf-8"?>
<transitionSet xmlns:android="http://schemas.android.com/apk/res/android">
    <changeBounds
        android:duration="1000"
        android:startDelay="0"
        />
</transitionSet>

这里写图片描述

整个 Activity 还是从底部进入,但是共享元素有自己的动画。

猜你喜欢

转载自blog.csdn.net/qq_18983205/article/details/78828413
今日推荐