Android开发教程案例源码分享-匹配动画多个头像飘动效果

Android开发教程案例源码分享-匹配动画多个头像飘动效果

匹配往往出现多个头像飘动,吸引人点击,有时出现的位置还不固定

一、思路:

用MotionLayout

二、效果图:

看视频更直观点:

Android开发教程案例源码分享-匹配动画多个头像飘动效果

三、关键代码:

xml布局

xml 复制代码
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:background="@color/color_1F1C4C">




    <androidx.core.widget.NestedScrollView
        android:layout_width="match_parent"
        android:layout_height="0dp"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintBottom_toBottomOf="parent">

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


            <androidx.constraintlayout.widget.ConstraintLayout
                android:id="@+id/cl_img_anim"
                android:layout_width="@dimen/dp_240"
                android:layout_height="@dimen/dp_240"
                android:layout_gravity="center_horizontal"
                android:layout_marginTop="@dimen/dp_70"
                >
                <ImageView
                    android:id="@+id/iv_video_match"
                    android:layout_width="match_parent"
                    android:layout_height="match_parent"
                    android:src="@mipmap/img_video_match"
                   />
            </androidx.constraintlayout.widget.ConstraintLayout>







            <androidx.constraintlayout.motion.widget.MotionLayout
                android:id="@+id/cl_amin1"
                android:layout_width="match_parent"
                android:layout_height="@dimen/dp_340"
                android:layout_marginTop="@dimen/dp_20"
                app:layoutDescription="@xml/activity_video_match_scene1"
                >

                <ImageView
                    android:id="@+id/iv_anim1"
                    android:layout_width="@dimen/dp_50"
                    android:layout_height="@dimen/dp_50"
                    app:layout_constraintLeft_toLeftOf="parent"
                    app:layout_constraintRight_toRightOf="parent"
                    app:layout_constraintTop_toTopOf="parent"
                    app:layout_constraintBottom_toBottomOf="parent"
                    android:scaleType="centerCrop"
                    android:src="@mipmap/yishi"

                    />


            </androidx.constraintlayout.motion.widget.MotionLayout>

            <androidx.constraintlayout.motion.widget.MotionLayout
                android:id="@+id/cl_amin2"
                android:layout_width="match_parent"
                android:layout_height="@dimen/dp_340"
                android:layout_marginTop="@dimen/dp_20"
                app:layoutDescription="@xml/activity_video_match_scene2"

                >

                <ImageView
                    android:id="@+id/iv_anim2"
                    android:layout_width="@dimen/dp_50"
                    android:layout_height="@dimen/dp_50"
                    app:layout_constraintLeft_toLeftOf="parent"
                    app:layout_constraintRight_toRightOf="parent"
                    app:layout_constraintTop_toTopOf="parent"
                    app:layout_constraintBottom_toBottomOf="parent"
                    android:src="@mipmap/yishi2"
                    android:scaleType="centerCrop"

                    />


            </androidx.constraintlayout.motion.widget.MotionLayout>

            <androidx.constraintlayout.motion.widget.MotionLayout
                android:id="@+id/cl_amin3"
                android:layout_width="match_parent"
                android:layout_height="@dimen/dp_340"
                android:layout_marginTop="@dimen/dp_20"
                app:layoutDescription="@xml/activity_video_match_scene3"

                >

                <ImageView
                    android:id="@+id/iv_anim3"
                    android:layout_width="@dimen/dp_50"
                    android:layout_height="@dimen/dp_50"
                    app:layout_constraintLeft_toLeftOf="parent"
                    app:layout_constraintRight_toRightOf="parent"
                    app:layout_constraintTop_toTopOf="parent"
                    app:layout_constraintBottom_toBottomOf="parent"
                    android:src="@mipmap/yishi3"
                    android:scaleType="centerCrop"
                    />

            </androidx.constraintlayout.motion.widget.MotionLayout>


            <androidx.constraintlayout.motion.widget.MotionLayout
                android:id="@+id/cl_amin4"
                android:layout_width="match_parent"
                android:layout_height="@dimen/dp_340"
                android:layout_marginTop="@dimen/dp_20"
                app:layoutDescription="@xml/activity_video_match_scene4"

                >

                <ImageView
                    android:id="@+id/iv_anim4"
                    android:layout_width="@dimen/dp_50"
                    android:layout_height="@dimen/dp_50"
                    app:layout_constraintLeft_toLeftOf="parent"
                    app:layout_constraintRight_toRightOf="parent"
                    app:layout_constraintTop_toTopOf="parent"
                    app:layout_constraintBottom_toBottomOf="parent"
                    android:src="@mipmap/yishi4"
                    android:scaleType="centerCrop"
                    />

            </androidx.constraintlayout.motion.widget.MotionLayout>

            <androidx.constraintlayout.motion.widget.MotionLayout
                android:id="@+id/cl_amin5"
                android:layout_width="match_parent"
                android:layout_height="@dimen/dp_340"
                android:layout_marginTop="@dimen/dp_20"
                app:layoutDescription="@xml/activity_video_match_scene5"

                >

                <ImageView
                    android:id="@+id/iv_anim5"
                    android:layout_width="@dimen/dp_50"
                    android:layout_height="@dimen/dp_50"
                    app:layout_constraintLeft_toLeftOf="parent"
                    app:layout_constraintRight_toRightOf="parent"
                    app:layout_constraintTop_toTopOf="parent"
                    app:layout_constraintBottom_toBottomOf="parent"
                    android:src="@mipmap/yishi5"
                    android:scaleType="centerCrop"
                    />

            </androidx.constraintlayout.motion.widget.MotionLayout>

            <androidx.constraintlayout.motion.widget.MotionLayout
                android:id="@+id/cl_amin6"
                android:layout_width="match_parent"
                android:layout_height="@dimen/dp_340"
                android:layout_marginTop="@dimen/dp_20"
                app:layoutDescription="@xml/activity_video_match_scene6"
                >

                <ImageView
                    android:id="@+id/iv_anim6"
                    android:layout_width="@dimen/dp_50"
                    android:layout_height="@dimen/dp_50"
                    app:layout_constraintLeft_toLeftOf="parent"
                    app:layout_constraintRight_toRightOf="parent"
                    app:layout_constraintTop_toTopOf="parent"
                    app:layout_constraintBottom_toBottomOf="parent"
                    android:src="@mipmap/yishi6"
                    android:scaleType="centerCrop"
                    />

            </androidx.constraintlayout.motion.widget.MotionLayout>

            <androidx.constraintlayout.motion.widget.MotionLayout
                android:id="@+id/cl_amin7"
                android:layout_width="match_parent"
                android:layout_height="@dimen/dp_340"
                android:layout_marginTop="@dimen/dp_20"
                app:layoutDescription="@xml/activity_video_match_scene7"
                >

                <ImageView
                    android:id="@+id/iv_anim7"
                    android:layout_width="@dimen/dp_50"
                    android:layout_height="@dimen/dp_50"
                    app:layout_constraintLeft_toLeftOf="parent"
                    app:layout_constraintRight_toRightOf="parent"
                    app:layout_constraintTop_toTopOf="parent"
                    app:layout_constraintBottom_toBottomOf="parent"
                    android:src="@mipmap/yishi7"
                    android:scaleType="centerCrop"
                    />

            </androidx.constraintlayout.motion.widget.MotionLayout>


        </FrameLayout>

    </androidx.core.widget.NestedScrollView>



</androidx.constraintlayout.widget.ConstraintLayout>

kotlin代码

kotlin 复制代码
package com.cong.mymoreheadanim

import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.os.Handler
import android.view.View
import androidx.constraintlayout.motion.widget.MotionLayout
import com.cong.mymoreheadanim.databinding.ActivityVideoMatchBinding
import com.zailiaoliao.lib.image.ImageLoader

class MainActivity : AppCompatActivity() {

    lateinit var mBinding:ActivityVideoMatchBinding
    private var isStart2 = false
    private var isStart3 = false
    private var isStart4 = false
    private var isStart5 = false
    private var isStart6 = false
    private var isStart7 = false

    private var isStartAnim1 = false


    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        mBinding = ActivityVideoMatchBinding.inflate(layoutInflater)
        setContentView(mBinding.root)


            ImageLoader.loadAvatar(mBinding.ivAnim1,R.mipmap.yishi)


            ImageLoader.loadAvatar(mBinding.ivAnim2,R.mipmap.yishi2)


            ImageLoader.loadAvatar(mBinding.ivAnim3,R.mipmap.yishi3)


            ImageLoader.loadAvatar(mBinding.ivAnim4,R.mipmap.yishi4)


            ImageLoader.loadAvatar(mBinding.ivAnim5,R.mipmap.yishi5)


            ImageLoader.loadAvatar(mBinding.ivAnim6,R.mipmap.yishi6)


            ImageLoader.loadAvatar(mBinding.ivAnim7,R.mipmap.yishi7)



        dealAnimListener()

    }

    override fun onResume() {
        super.onResume()
        if (!isStartAnim1){
            Handler().postDelayed({
                mBinding.clAmin1.transitionToStart()
                mBinding.clAmin1.setTransition(R.id.left_to_right)
                mBinding.clAmin1.transitionToEnd()
                isStartAnim1 = true
            },500)

        }

    }

    private fun dealAnimListener(){
        mBinding.clAmin1.addTransitionListener(object : MotionLayout.TransitionListener{
            override fun onTransitionStarted(p0: MotionLayout?, p1: Int, p2: Int) {
                mBinding.ivAnim1.visibility = View.VISIBLE
            }

            override fun onTransitionChange(p0: MotionLayout?, p1: Int, p2: Int, p3: Float) {
                if (p3 >= 0.2f && !isStart2){
                    mBinding.clAmin2.transitionToStart()
                    mBinding.clAmin2.setTransition(R.id.left_to_right2)
                    mBinding.clAmin2.transitionToEnd()
                    isStart2 = true
                }
            }

            override fun onTransitionCompleted(p0: MotionLayout, p1: Int) {
                isStart2 = false
            }

            override fun onTransitionTrigger(p0: MotionLayout?, p1: Int, p2: Boolean, p3: Float) {

            }

        })

        mBinding.clAmin2.addTransitionListener(object : MotionLayout.TransitionListener{
            override fun onTransitionStarted(p0: MotionLayout?, p1: Int, p2: Int) {
                mBinding.ivAnim2.visibility = View.VISIBLE
            }

            override fun onTransitionChange(p0: MotionLayout?, p1: Int, p2: Int, p3: Float) {
                if (p3 >= 0.2f && !isStart3){
                    mBinding.clAmin3.transitionToStart()
                    mBinding.clAmin3.setTransition(R.id.left_to_right3)
                    mBinding.clAmin3.transitionToEnd()
                    isStart3 = true
                }
            }

            override fun onTransitionCompleted(p0: MotionLayout, p1: Int) {
                isStart3 = false
            }

            override fun onTransitionTrigger(p0: MotionLayout?, p1: Int, p2: Boolean, p3: Float) {

            }

        })

        mBinding.clAmin3.addTransitionListener(object : MotionLayout.TransitionListener{
            override fun onTransitionStarted(p0: MotionLayout?, p1: Int, p2: Int) {
                mBinding.ivAnim3.visibility = View.VISIBLE
            }

            override fun onTransitionChange(p0: MotionLayout?, p1: Int, p2: Int, p3: Float) {
                if (p3 >= 0.5f && !isStart4){
                    mBinding.clAmin4.transitionToStart()
                    mBinding.clAmin4.setTransition(R.id.left_to_right4)
                    mBinding.clAmin4.transitionToEnd()
                    isStart4 = true
                }
            }

            override fun onTransitionCompleted(p0: MotionLayout, p1: Int) {
                isStart4 = false
            }

            override fun onTransitionTrigger(p0: MotionLayout?, p1: Int, p2: Boolean, p3: Float) {

            }

        })

        mBinding.clAmin4.addTransitionListener(object : MotionLayout.TransitionListener{
            override fun onTransitionStarted(p0: MotionLayout?, p1: Int, p2: Int) {
                mBinding.ivAnim4.visibility = View.VISIBLE
            }

            override fun onTransitionChange(p0: MotionLayout?, p1: Int, p2: Int, p3: Float) {
                if (p3 >= 0.3f && !isStart5){
                    mBinding.clAmin5.transitionToStart()
                    mBinding.clAmin5.setTransition(R.id.left_to_right5)
                    mBinding.clAmin5.transitionToEnd()
                    isStart5 = true
                }
            }

            override fun onTransitionCompleted(p0: MotionLayout, p1: Int) {
                isStart5 = false
            }

            override fun onTransitionTrigger(p0: MotionLayout?, p1: Int, p2: Boolean, p3: Float) {

            }

        })

        mBinding.clAmin5.addTransitionListener(object : MotionLayout.TransitionListener{
            override fun onTransitionStarted(p0: MotionLayout?, p1: Int, p2: Int) {
                mBinding.ivAnim5.visibility = View.VISIBLE
            }

            override fun onTransitionChange(p0: MotionLayout?, p1: Int, p2: Int, p3: Float) {
                if (p3 >= 0.3f && !isStart6){
                    mBinding.clAmin6.transitionToStart()
                    mBinding.clAmin6.setTransition(R.id.left_to_right6)
                    mBinding.clAmin6.transitionToEnd()
                    isStart6 = true
                }
            }

            override fun onTransitionCompleted(p0: MotionLayout, p1: Int) {
                isStart6 = false

            }

            override fun onTransitionTrigger(p0: MotionLayout?, p1: Int, p2: Boolean, p3: Float) {

            }

        })

        mBinding.clAmin6.addTransitionListener(object : MotionLayout.TransitionListener{
            override fun onTransitionStarted(p0: MotionLayout?, p1: Int, p2: Int) {
                mBinding.ivAnim6.visibility = View.VISIBLE
            }

            override fun onTransitionChange(p0: MotionLayout?, p1: Int, p2: Int, p3: Float) {
                if (p3 >= 0.3f && !isStart7){
                    mBinding.clAmin7.transitionToStart()
                    mBinding.clAmin7.setTransition(R.id.left_to_right7)
                    mBinding.clAmin7.transitionToEnd()
                    isStart7 = true
                }
            }

            override fun onTransitionCompleted(p0: MotionLayout, p1: Int) {
                isStart7 = false
                mBinding.ivAnim1.visibility = View.GONE
                mBinding.clAmin1.transitionToStart()
                mBinding.clAmin1.setTransition(R.id.left_to_right)
                mBinding.clAmin1.transitionToEnd()
            }

            override fun onTransitionTrigger(p0: MotionLayout?, p1: Int, p2: Boolean, p3: Float) {

            }

        })

        mBinding.clAmin7.addTransitionListener(object : MotionLayout.TransitionListener{
            override fun onTransitionStarted(p0: MotionLayout?, p1: Int, p2: Int) {
                mBinding.ivAnim7.visibility = View.VISIBLE
            }

            override fun onTransitionChange(p0: MotionLayout?, p1: Int, p2: Int, p3: Float) {
            }

            override fun onTransitionCompleted(p0: MotionLayout, p1: Int) {
            }

            override fun onTransitionTrigger(p0: MotionLayout?, p1: Int, p2: Boolean, p3: Float) {

            }

        })

    }
}
项目demo源码结构图:

有问题或者需要demo源码的私信我

相关推荐
阿豪元代码9 分钟前
Perfetto 上手指南3 —— CPU 信息分析
android
宋智孝的小迷弟18 分钟前
Android 异步数据流:Kotlin Flow 为何成为新一代“利器”?LiveData 又有何局限?
android·面试·app
AD钙奶-lalala1 小时前
Android 11以上App主动连接WIFI的完整方案
android
大耳猫1 小时前
Android 中的 DataBinding 详解
android·android jetpack·databinding
玲小珑2 小时前
Auto.js 入门指南(一)什么是 Auto.js
android·前端
Fastcv3 小时前
手把手教你上传安卓库到Central Portal
android·maven·jcenter
whysqwhw3 小时前
安卓应用线程与架构问题
android
小鱼干coc3 小时前
Android 轻松实现 增强版灵活的 滑动式表格视图
android
Le_ee3 小时前
dvwa6——Insecure CAPTCHA
android·安全·网络安全·靶场·dvwa
django-尿素4 小时前
django入门-orm数据库操作
android·数据库·django