Lottie动画学习(Kotlin)

2023-05-16

最近一直在学习kotlin,又接触到 Lottie 动画,网上是Java写的 Lottie动画,我用kotlin写了一边,发现了一写问题。总结一下

Lottie学习文章

Lottie for Android GitHub

Lottie,简单的说,流程就是(Android为例):UI设计给出动画的 Json 文件,放到项目中,加载,展示动画。

特别说明一下:Lottie 2.8.0,对应的最小SDK,一定要 大于等于16(Android 4.1)。现在很少有低于4.1了吧,注意下就好

我网上找了个动画对应的Json

出自文章:Lottie开源动画库介绍与使用示例

现在,开始使用:
这里,我先讲一下Java的使用,很简单:
1、我项目中,是用的 androidx

implementation "com.airbnb.android:lottie:2.8.0"

2、res文件夹下,创建raw文件夹,然后,创建一个:hello_world.json 文件
(上面提到的,学习文章中,有这么一句:建议使用 res/raw,因为可以对动画通过 R 文件使用静态引用,而不只是使用字符串名称)
3、把上面提到的,动画对应的 json,复制到 hello_world.json 文件中
4、布局文件:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <com.airbnb.lottie.LottieAnimationView
        android:background="#55ff0000"
        android:id="@+id/animation_view"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerInParent="true"
        app:lottie_loop="true"
        app:lottie_rawRes="@raw/hello_world" />

</RelativeLayout>

5、代码中使用:

	private boolean animationStatus = false;
	
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main_2);

        final LottieAnimationView animationView = findViewById(R.id.animation_view);

        animationView.playAnimation();

        animationView.addAnimatorListener(new Animator.AnimatorListener() {
            @Override
            public void onAnimationStart(Animator animation) {
                animationStatus = true;
                Log.e("getAnimatedValue()", "onAnimationStart==" + animationView.isAnimating());
            }

            @Override
            public void onAnimationEnd(Animator animation) {
                animationStatus = false;
                Log.e("getAnimatedValue()", "onAnimationEnd==" + animationView.isAnimating());
            }

            @Override
            public void onAnimationCancel(Animator animation) {
                animationStatus = false;
                Log.e("getAnimatedValue()", "onAnimationCancel==" + animationView.isAnimating());
            }

            @Override
            public void onAnimationRepeat(Animator animation) {
                animationStatus = true;
                Log.e("getAnimatedValue()", "onAnimationRepeat==" + animationView.isAnimating());
            }
        });

        //animationView.addAnimatorUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
        //  @Override
        //  public void onAnimationUpdate(ValueAnimator animation) {
        //      Log.e("getAnimatedValue()",animation.getAnimatedValue()+"");
        //  }
        //});

        animationView.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {

                if (animationStatus) {
                    animationView.cancelAnimation();
                } else {
                    animationView.playAnimation();
                }
            }
        });
    }

到这里,使用就结束了。很简单。

接下来,用kotlin实现一下。
新建kotlin项目,然后引入依赖

dependencies {
    implementation fileTree(dir: 'libs', include: ['*.jar'])
    implementation"org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
    implementation 'com.android.support:appcompat-v7:28.0.0'
    implementation 'com.android.support.constraint:constraint-layout:1.1.3'
    testImplementation 'junit:junit:4.12'
    androidTestImplementation 'com.android.support.test:runner:1.0.2'
    androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
    implementation 'com.android.support:recyclerview-v7:28.0.0'

    implementation "com.airbnb.android:lottie:2.8.0"
}

这里,注意一下:新建后,默认的是:com.android.support

然后,和上面一样了,区别在于Activity中的使用写法:

    <com.airbnb.lottie.LottieAnimationView
            android:background="#55ff0000"
            android:id="@+id/animation_view"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_centerInParent="true"
            app:lottie_loop="true"
            app:lottie_rawRes="@raw/hello_world" />

注意,id 是 animation_view

	//动画状态,默认是false:不运动
    var animationStatus: Boolean = false

    override fun initView() {
        setContentView(R.layout.activity_main_5)

        animation_view.playAnimation()

        animation_view.addAnimatorListener(object : Animator.AnimatorListener {
            override fun onAnimationRepeat(animation: Animator?) {
                animationStatus = true
                Utils.logE("addAnimatorListener == onAnimationRepeat == " + animation_view.isAnimating)
            }

            override fun onAnimationEnd(animation: Animator?) {
                animationStatus = false
                Utils.logE("addAnimatorListener == onAnimationEnd == " + animation_view.isAnimating)
            }

            override fun onAnimationCancel(animation: Animator?) {
                animationStatus = false
                Utils.logE("addAnimatorListener == onAnimationCancel == " + animation_view.isAnimating)
            }

            override fun onAnimationStart(animation: Animator?) {
                animationStatus = true
                Utils.logE("addAnimatorListener == onAnimationStart ==" + animation_view.isAnimating)
            }
        })

        animation_view.setOnClickListener(object : View.OnClickListener {
            override fun onClick(v: View?) {

                if (animationStatus) {
                    animation_view.cancelAnimation()
                } else {
                    animation_view.playAnimation()
                }
            }
        })
    }

然后,运行,就会报错了:

* What went wrong:
Execution failed for task ':app:processDebugManifest'.
> Manifest merger failed : Attribute application@appComponentFactory value=(android.support.v4.app.CoreComponentFactory) from [com.android.support:support-compat:28.0.0] AndroidManifest.xml:22:18-91
  	is also present at [androidx.core:core:1.0.0] AndroidManifest.xml:22:18-86 value=(androidx.core.app.CoreComponentFactory).
  	Suggestion: add 'tools:replace="android:appComponentFactory"' to <application> element at AndroidManifest.xml:5:5-31:19 to override.

出了什么问题:
任务':app:processDebugManifest'执行失败。
清单合并失败:属性application@appComponentFactory value=(android. android.support:support-compat:28.0.0) from [com.android.support: compat:28.0.0] AndroidManifest.xml:22:18-91
也存在于[androidx.core:core:1.0.0] AndroidManifest。xml: 22:18 - 86值= (androidx.core.app.CoreComponentFactory)。
建议:在AndroidManifest的 element中添加'tools:replace="android:appComponentFactory"'。xml: 5:5-31:19覆盖。

我试过所谓的清单文件中的加属性,没用。
出现这个问题,是因为 androidx 和 android.support 冲突了!
即:androidx 和 项目中默认的 android.support,冲突了!
但是,我们没有写 androidx 啊,它在哪里有使用或者出现呢?
去看下Lottie的源码下的 build.gradle
里面明确有一句:

implementation "androidx.appcompat:appcompat:${androidXVersion}"

解决办法:
1、共存。让 androidx 和 android.support 共存。这样比较麻烦,代价也大
2、在这里插入图片描述
处理之后:

dependencies {
    implementation fileTree(dir: 'libs', include: ['*.jar'])
    implementation 'androidx.appcompat:appcompat:1.0.0-beta01'
    implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
    testImplementation 'junit:junit:4.12'
    androidTestImplementation 'androidx.test:runner:1.1.0-alpha4'
    androidTestImplementation 'androidx.test.espresso:espresso-core:3.1.0-alpha4'

    implementation 'androidx.room:room-runtime:2.0.0-beta01'
    annotationProcessor 'androidx.room:room-compiler:2.0.0-beta01'

    implementation "com.airbnb.android:lottie:2.8.0"

}

最后,特别说明一下:
我在xml的布局文件中,指定了,动画是无限循环的。
那么,对应的动画状态是:

start -> 执行 -> 一次执行完 -> repeat -> 执行 -> ...

当执行方法

cancelAnimation()

后,状态是 cancel,但是,这个时候,

@Override
public void onAnimationCancel(Animator animation) {
	Log.e("getAnimatedValue()", "onAnimationCancel==" + animationView.isAnimating());
}
日志:true

源码中执行方法顺序我没找到,不过,看属性动画的源码,是cancel,在end之前执行的,这里,应该也是。end,对应的 animationView.isAnimating() -> false

如果,动画只执行一次,状态是:

start -> 执行 -> end 

@Override
public void onAnimationEnd(Animator animation) {
	Log.e("getAnimatedValue()", "onAnimationEnd==" + animationView.isAnimating());
}
日志:false
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Lottie动画学习(Kotlin) 的相关文章

随机推荐