[6.7.0][Feat]切换高精地图和高德地图且带动画
This commit is contained in:
@@ -0,0 +1,282 @@
|
||||
package com.mogo.eagle.core.function.hmi.map
|
||||
|
||||
import android.animation.Animator
|
||||
import android.animation.AnimatorSet
|
||||
import android.animation.ObjectAnimator
|
||||
import android.content.Context
|
||||
import android.util.AttributeSet
|
||||
import android.view.View
|
||||
import android.view.animation.AccelerateDecelerateInterpolator
|
||||
import androidx.constraintlayout.widget.ConstraintLayout
|
||||
|
||||
class ExchangeChildLayout @JvmOverloads constructor(
|
||||
context: Context,
|
||||
attrs: AttributeSet? = null,
|
||||
defStyleAttr: Int = 0
|
||||
) : ConstraintLayout(context, attrs, defStyleAttr) {
|
||||
|
||||
private var mContext: Context? = null
|
||||
private var isChange = false
|
||||
private var isPlayingAnim = false
|
||||
|
||||
private var maxWidth = 0
|
||||
private var maxHeight = 0
|
||||
private var minWidth = 0
|
||||
private var minHeight = 0
|
||||
private var bottomX = 0f
|
||||
private var bottomY = 0f
|
||||
private var topX = 0f
|
||||
private var topY = 0f
|
||||
|
||||
companion object {
|
||||
private const val TAG = "ExchangeChildLayout"
|
||||
private const val ANIM_DURATION = 600L
|
||||
}
|
||||
|
||||
init {
|
||||
try {
|
||||
initView(context)
|
||||
} catch (e: Exception) {
|
||||
e.printStackTrace()
|
||||
}
|
||||
}
|
||||
|
||||
private fun initView(context: Context) {
|
||||
mContext = context
|
||||
}
|
||||
|
||||
override fun onWindowFocusChanged(hasWindowFocus: Boolean) {
|
||||
super.onWindowFocusChanged(hasWindowFocus)
|
||||
if (hasWindowFocus) {
|
||||
val bottomView = getChildAt(0)
|
||||
val topView = getChildAt(childCount - 1)
|
||||
maxWidth = bottomView.width
|
||||
maxHeight = bottomView.height
|
||||
minWidth = topView.width
|
||||
minHeight = topView.height
|
||||
bottomX = bottomView.x
|
||||
bottomY = bottomView.y
|
||||
topX = topView.x
|
||||
topY = topView.y
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 开启ViewGroup自定义绘制顺序
|
||||
*/
|
||||
fun setCustomOrder(enable: Boolean) {
|
||||
isChildrenDrawingOrderEnabled = enable
|
||||
}
|
||||
|
||||
/**
|
||||
* 切换高精地图和高德地图View的位置
|
||||
*/
|
||||
fun exchange() {
|
||||
if (!isPlayingAnim) {
|
||||
isChange = !isChange
|
||||
startAnim()
|
||||
invalidate()
|
||||
}
|
||||
}
|
||||
|
||||
private fun startAnim() {
|
||||
val bottomView = getChildAt(0)
|
||||
val topView = getChildAt(childCount - 1)
|
||||
|
||||
val bottomXAnimator: ObjectAnimator
|
||||
val bottomYAnimator: ObjectAnimator
|
||||
val bottomWidthAnimator: ObjectAnimator
|
||||
val bottomHeightAnimator: ObjectAnimator
|
||||
val topXAnimator: ObjectAnimator
|
||||
val topYAnimator: ObjectAnimator
|
||||
val topWidthAnimator: ObjectAnimator
|
||||
val topHeightAnimator: ObjectAnimator
|
||||
|
||||
if (isChange) {
|
||||
exchangeRule(bottomView.layoutParams as LayoutParams, true, true)
|
||||
bottomXAnimator = ObjectAnimator.ofFloat(bottomView, "x", bottomX, topX)
|
||||
bottomYAnimator = ObjectAnimator.ofFloat(bottomView, "y", bottomY, topY)
|
||||
bottomWidthAnimator =
|
||||
ObjectAnimator.ofInt(
|
||||
WrapperViewWidth(bottomView),
|
||||
"width",
|
||||
maxWidth,
|
||||
minWidth
|
||||
)
|
||||
bottomHeightAnimator =
|
||||
ObjectAnimator.ofInt(
|
||||
WrapperViewHeight(bottomView),
|
||||
"height",
|
||||
maxHeight,
|
||||
minHeight
|
||||
)
|
||||
exchangeRule(topView.layoutParams as LayoutParams, false, true)
|
||||
topXAnimator = ObjectAnimator.ofFloat(topView, "x", topX, bottomX)
|
||||
topYAnimator = ObjectAnimator.ofFloat(topView, "y", topY, bottomY)
|
||||
topWidthAnimator =
|
||||
ObjectAnimator.ofInt(
|
||||
WrapperViewWidth(topView),
|
||||
"width",
|
||||
minWidth,
|
||||
maxWidth
|
||||
)
|
||||
topHeightAnimator =
|
||||
ObjectAnimator.ofInt(
|
||||
WrapperViewHeight(topView),
|
||||
"height",
|
||||
minHeight,
|
||||
maxHeight
|
||||
)
|
||||
} else {
|
||||
exchangeRule(bottomView.layoutParams as LayoutParams, true, false)
|
||||
bottomXAnimator = ObjectAnimator.ofFloat(bottomView, "x", topX, bottomX)
|
||||
bottomYAnimator = ObjectAnimator.ofFloat(bottomView, "y", topY, bottomY)
|
||||
bottomWidthAnimator =
|
||||
ObjectAnimator.ofInt(
|
||||
WrapperViewWidth(bottomView),
|
||||
"width",
|
||||
minWidth,
|
||||
maxWidth
|
||||
)
|
||||
bottomHeightAnimator =
|
||||
ObjectAnimator.ofInt(
|
||||
WrapperViewHeight(bottomView),
|
||||
"height",
|
||||
minHeight,
|
||||
maxHeight
|
||||
)
|
||||
exchangeRule(topView.layoutParams as LayoutParams, false, false)
|
||||
topXAnimator = ObjectAnimator.ofFloat(topView, "x", bottomX, topX)
|
||||
topYAnimator = ObjectAnimator.ofFloat(topView, "y", bottomY, topY)
|
||||
topWidthAnimator =
|
||||
ObjectAnimator.ofInt(
|
||||
WrapperViewWidth(topView),
|
||||
"width",
|
||||
maxWidth,
|
||||
minWidth
|
||||
)
|
||||
topHeightAnimator =
|
||||
ObjectAnimator.ofInt(
|
||||
WrapperViewHeight(topView),
|
||||
"height",
|
||||
maxHeight,
|
||||
minHeight
|
||||
)
|
||||
}
|
||||
|
||||
// 将多个动画组合在一起
|
||||
val animatorSet = AnimatorSet()
|
||||
animatorSet.playTogether(
|
||||
bottomXAnimator,
|
||||
bottomYAnimator,
|
||||
bottomWidthAnimator,
|
||||
bottomHeightAnimator,
|
||||
topXAnimator,
|
||||
topYAnimator,
|
||||
topWidthAnimator,
|
||||
topHeightAnimator
|
||||
)
|
||||
animatorSet.addListener(object : Animator.AnimatorListener {
|
||||
override fun onAnimationStart(animation: Animator) {
|
||||
isPlayingAnim = true
|
||||
}
|
||||
|
||||
override fun onAnimationEnd(animation: Animator) {
|
||||
isPlayingAnim = false
|
||||
}
|
||||
|
||||
override fun onAnimationCancel(animation: Animator) {
|
||||
isPlayingAnim = false
|
||||
}
|
||||
|
||||
override fun onAnimationRepeat(animation: Animator) {
|
||||
|
||||
}
|
||||
})
|
||||
animatorSet.duration = ANIM_DURATION
|
||||
animatorSet.interpolator = AccelerateDecelerateInterpolator()
|
||||
// 启动动画
|
||||
animatorSet.start()
|
||||
}
|
||||
|
||||
fun getChangeFlag() = isChange
|
||||
|
||||
override fun isChildrenDrawingOrderEnabled() = super.isChildrenDrawingOrderEnabled()
|
||||
|
||||
override fun getChildDrawingOrder(childCount: Int, i: Int): Int {
|
||||
return if (isChange) {
|
||||
when (i) {
|
||||
0 -> {
|
||||
childCount - 1
|
||||
}
|
||||
|
||||
childCount - 1 -> {
|
||||
0
|
||||
}
|
||||
|
||||
else -> {
|
||||
i
|
||||
}
|
||||
}
|
||||
} else {
|
||||
super.getChildDrawingOrder(childCount, i)
|
||||
}
|
||||
}
|
||||
|
||||
// 用于包装 View 的宽度,以便可以使用 ObjectAnimator 来改变宽度
|
||||
class WrapperViewWidth(
|
||||
private val view: View,
|
||||
) {
|
||||
var width: Int
|
||||
get() = view.layoutParams.width
|
||||
set(width) {
|
||||
val layoutParams = view.layoutParams as LayoutParams
|
||||
layoutParams.width = width
|
||||
view.layoutParams = layoutParams
|
||||
}
|
||||
}
|
||||
|
||||
class WrapperViewHeight(
|
||||
private val view: View,
|
||||
) {
|
||||
|
||||
var height: Int
|
||||
get() = view.layoutParams.height
|
||||
set(height) {
|
||||
val layoutParams = view.layoutParams as LayoutParams
|
||||
layoutParams.height = height
|
||||
view.layoutParams = layoutParams
|
||||
}
|
||||
}
|
||||
|
||||
private fun exchangeRule(
|
||||
layoutParams: LayoutParams, isBottom: Boolean,
|
||||
isChange: Boolean
|
||||
) {
|
||||
if (isBottom) {
|
||||
if (isChange) {
|
||||
layoutParams.startToStart = LayoutParams.UNSET
|
||||
layoutParams.topToTop = LayoutParams.UNSET
|
||||
layoutParams.endToEnd = LayoutParams.PARENT_ID
|
||||
layoutParams.bottomToBottom = LayoutParams.PARENT_ID
|
||||
} else {
|
||||
layoutParams.startToStart = LayoutParams.PARENT_ID
|
||||
layoutParams.topToTop = LayoutParams.PARENT_ID
|
||||
layoutParams.endToEnd = LayoutParams.UNSET
|
||||
layoutParams.bottomToBottom = LayoutParams.UNSET
|
||||
}
|
||||
} else {
|
||||
if (isChange) {
|
||||
layoutParams.startToStart = LayoutParams.PARENT_ID
|
||||
layoutParams.topToTop = LayoutParams.PARENT_ID
|
||||
layoutParams.endToEnd = LayoutParams.UNSET
|
||||
layoutParams.bottomToBottom = LayoutParams.UNSET
|
||||
} else {
|
||||
layoutParams.startToStart = LayoutParams.UNSET
|
||||
layoutParams.topToTop = LayoutParams.UNSET
|
||||
layoutParams.endToEnd = LayoutParams.PARENT_ID
|
||||
layoutParams.bottomToBottom = LayoutParams.PARENT_ID
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user