Commit 5160a75b authored by jyx's avatar jyx

添加加金币动画效果

parent f003f5d4
package com.mints.helivideo.ui.fragment package com.mints.helivideo.ui.fragment
import android.animation.Animator
import android.animation.ValueAnimator
import android.graphics.Path
import android.graphics.PathMeasure
import android.view.LayoutInflater import android.view.LayoutInflater
import android.view.View import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
import android.view.animation.LinearInterpolator
import android.widget.Button import android.widget.Button
import android.widget.ImageView
import android.widget.RelativeLayout
import android.widget.Toast import android.widget.Toast
import androidx.annotation.Nullable import androidx.annotation.Nullable
import androidx.fragment.app.Fragment import androidx.fragment.app.Fragment
...@@ -13,7 +20,10 @@ import com.mints.helivideo.common.AppConfig ...@@ -13,7 +20,10 @@ import com.mints.helivideo.common.AppConfig
import com.mints.helivideo.common.Constant import com.mints.helivideo.common.Constant
import com.mints.helivideo.manager.DPHolder import com.mints.helivideo.manager.DPHolder
import com.mints.helivideo.ui.fragment.base.LazyLoadBaseFragment import com.mints.helivideo.ui.fragment.base.LazyLoadBaseFragment
import com.mints.helivideo.utils.BubbleUtils
import com.mints.helivideo.utils.LogUtil import com.mints.helivideo.utils.LogUtil
import kotlinx.android.synthetic.main.fragment_music.*
import kotlinx.android.synthetic.main.layout_draw_header.*
class MusicFragment : LazyLoadBaseFragment() { class MusicFragment : LazyLoadBaseFragment() {
...@@ -27,6 +37,14 @@ class MusicFragment : LazyLoadBaseFragment() { ...@@ -27,6 +37,14 @@ class MusicFragment : LazyLoadBaseFragment() {
override fun getContentViewLayoutID() = R.layout.fragment_music override fun getContentViewLayoutID() = R.layout.fragment_music
override fun initViewsAndEvents() { override fun initViewsAndEvents() {
btn1.setOnClickListener {
addAnimation(it, iv_gold)
}
btn2.setOnClickListener {
addAnimation(it, iv_cash)
}
} }
override fun onFragmentFirstVisible() { override fun onFragmentFirstVisible() {
...@@ -372,4 +390,105 @@ class MusicFragment : LazyLoadBaseFragment() { ...@@ -372,4 +390,105 @@ class MusicFragment : LazyLoadBaseFragment() {
}) })
) )
} }
//计算path路径中点的坐标
private var mPathMeasure: PathMeasure? = null
/**
* 贝塞尔曲线中间过程的点的坐标
*/
private val mCurrentPosition = FloatArray(2)
/**
* 动画
*/
private fun addAnimation(view: View, targetView: View) {
// 一、创造出执行动画的主题---imageview
//代码new一个imageview,图片资源是上面的imageview的图片
// (这个图片就是执行动画的图片,从开始位置出发,经过一个抛物线(贝塞尔曲线),移动到购物车里)
val goods = ImageView(requireContext())
goods.setImageDrawable(
resources.getDrawable(
R.mipmap.ic_launcher_main,
null
)
)
val params = RelativeLayout.LayoutParams(BubbleUtils.dp2px(30), BubbleUtils.dp2px(30))
rl.addView(goods, params)
// 二、计算动画开始/结束点的坐标的准备工作
//得到父布局的起始点坐标(用于辅助计算动画开始/结束时的点的坐标)
val parentLocation = IntArray(2)
rl.getLocationInWindow(parentLocation)
//得到商品图片的坐标(用于计算动画开始的坐标)
val startLoc = IntArray(2)
view.getLocationInWindow(startLoc)
//得到购物车图片的坐标(用于计算动画结束后的坐标)
val endLoc = IntArray(2)
targetView.getLocationInWindow(endLoc)
// 三、正式开始计算动画开始/结束的坐标
//开始掉落的商品的起始点:商品起始点-父布局起始点+该商品图片的一半
val startX =
startLoc[0] - parentLocation[0] + goods.width / 2.toFloat()
val startY =
startLoc[1] - parentLocation[1] + goods.height / 2.toFloat()
//商品掉落后的终点坐标:购物车起始点-父布局起始点+购物车图片的1/5
val toX =
endLoc[0] - parentLocation[0].toFloat()
// + targetView.width / 5.toFloat()
val toY = endLoc[1] - parentLocation[1].toFloat() + targetView.height / 5.toFloat()
//四、计算中间动画的插值坐标(贝塞尔曲线)(其实就是用贝塞尔曲线来完成起终点的过程)
//开始绘制贝塞尔曲线
val path = Path()
//移动到起始点(贝塞尔曲线的起点)
path.moveTo(startX, startY)
//使用二次萨贝尔曲线:注意第一个起始坐标越大,贝塞尔曲线的横向距离就会越大,一般按照下面的式子取即可
//想实现类似抛物线的形式,这里的控制点取的是(startX+toX)/2,startY
path.quadTo((startX + toX) / 2, startY, toX, toY)
//mPathMeasure用来计算贝塞尔曲线的曲线长度和贝塞尔曲线中间插值的坐标,
// 如果是true,path会形成一个闭环,Path用来计算path路径中的点的坐标
mPathMeasure = PathMeasure(path, false)
//★★★属性动画实现(从0到贝塞尔曲线的长度之间进行插值计算,获取中间过程的距离值)
val valueAnimator = ValueAnimator.ofFloat(0f, mPathMeasure!!.length)
valueAnimator.duration = 500
// 匀速线性插值器
valueAnimator.interpolator = LinearInterpolator()
valueAnimator.addUpdateListener { animation -> // 当插值计算进行时,获取中间的每个值,
// 这里这个值是中间过程中的曲线长度(下面根据这个值来得出中间点的坐标值)
val value = animation.animatedValue as Float
// ★★★★★获取当前点坐标封装到mCurrentPosition
// boolean getPosTan(float distance, float[] pos, float[] tan) :
// 传入一个距离distance(0<=distance<=getLength()),然后会计算当前距
// 离的坐标点和切线,pos会自动填充上坐标,这个方法很重要。
mPathMeasure!!.getPosTan(
value,
mCurrentPosition,
null
) //mCurrentPosition此时就是中间距离点的坐标值
// 移动的商品图片(动画图片)的坐标设置为该中间点的坐标
goods.translationX = mCurrentPosition[0]
goods.translationY = mCurrentPosition[1]
}
// 五、 开始执行动画
valueAnimator.start()
// 六、动画结束后的处理
valueAnimator.addListener(object : Animator.AnimatorListener {
override fun onAnimationStart(animation: Animator) {}
//当动画结束后:
override fun onAnimationEnd(animation: Animator) {
// 把移动的图片imageview从父布局里移除
rl.removeView(goods)
}
override fun onAnimationCancel(animation: Animator) {}
override fun onAnimationRepeat(animation: Animator) {}
})
}
} }
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/rl"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent"> android:layout_height="match_parent">
...@@ -10,4 +11,22 @@ ...@@ -10,4 +11,22 @@
<include layout="@layout/layout_draw_header" /> <include layout="@layout/layout_draw_header" />
<Button
android:id="@+id/btn1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_marginBottom="100dp"
android:background="@mipmap/ic_launcher_main" />
<Button
android:id="@+id/btn2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentEnd="true"
android:layout_alignParentBottom="true"
android:layout_marginBottom="100dp"
android:background="@mipmap/ic_launcher_main" />
</RelativeLayout> </RelativeLayout>
\ No newline at end of file
...@@ -14,6 +14,7 @@ ...@@ -14,6 +14,7 @@
android:gravity="center_vertical"> android:gravity="center_vertical">
<ImageView <ImageView
android:id="@+id/iv_cash"
android:layout_width="30dp" android:layout_width="30dp"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:src="@mipmap/ic_launcher_main" /> android:src="@mipmap/ic_launcher_main" />
...@@ -47,6 +48,7 @@ ...@@ -47,6 +48,7 @@
android:gravity="center_vertical"> android:gravity="center_vertical">
<ImageView <ImageView
android:id="@+id/iv_gold"
android:layout_width="30dp" android:layout_width="30dp"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:src="@mipmap/ic_launcher_main" /> android:src="@mipmap/ic_launcher_main" />
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment