Android 如何直接(无动画)设置晶圆厂图标旋转&;运行时的颜色和晶圆厂背景? 背景

Android 如何直接(无动画)设置晶圆厂图标旋转&;运行时的颜色和晶圆厂背景? 背景,android,floating-action-button,objectanimator,Android,Floating Action Button,Objectanimator,我正在制作一个上下滑动晶圆厂的POC,类似于当你接到电话时,它在手机应用程序上的工作方式: 问题 虽然我已经处理了触摸事件(允许上下移动晶圆厂),并在停止触摸时设置动画,但我还需要更改晶圆厂的背景颜色以及晶圆厂图标的旋转和颜色 我发现了什么 我只找到了制作晶圆厂背景色及其图标旋转动画的解决方案: 不过,我没有找到如何更改图标本身的颜色 但在我的例子中,它不能只用动画来完成,因为晶圆厂的Y坐标是基于触摸而变化的,所以这些值需要立即调整,而不需要动画 以下是我当前的代码: 活动\u mai

我正在制作一个上下滑动晶圆厂的POC,类似于当你接到电话时,它在手机应用程序上的工作方式:

问题 虽然我已经处理了触摸事件(允许上下移动晶圆厂),并在停止触摸时设置动画,但我还需要更改晶圆厂的背景颜色以及晶圆厂图标的旋转和颜色

我发现了什么 我只找到了制作晶圆厂背景色及其图标旋转动画的解决方案:

不过,我没有找到如何更改图标本身的颜色

但在我的例子中,它不能只用动画来完成,因为晶圆厂的Y坐标是基于触摸而变化的,所以这些值需要立即调整,而不需要动画

以下是我当前的代码:

活动\u main.xml

<FrameLayout
    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" android:clipChildren="false" android:clipToPadding="false"
    tools:context=".MainActivity">

    <FrameLayout
        android:id="@+id/fabTouchingAreaView" android:layout_width="match_parent" android:layout_height="wrap_content"
        android:layout_gravity="bottom|center_horizontal" android:layout_margin="@dimen/fab_margin"
        android:clipChildren="false" android:clipToPadding="false" tools:background="#33ff0000">

        <com.google.android.material.floatingactionbutton.FloatingActionButton
            android:id="@+id/fab" android:layout_width="match_parent" android:layout_height="wrap_content"
            android:layout_gravity="center_horizontal|bottom" android:layout_marginBottom="20dp"
            android:layout_marginTop="50dp" android:tint="#0f0" app:backgroundTint="#fff"
            app:srcCompat="@android:drawable/stat_sys_phone_call"/>
    </FrameLayout>
</FrameLayout>
如何在运行时更改晶圆厂的背景色,类似于 到手机应用程序,只使用我走了多远的百分比

您可以使用
argbeevaluator
计算当前位置的颜色,并将
evaluate
的返回值设置为新背景

如何在运行时更改晶圆厂图标的旋转, 与手机应用程序类似,只使用了我 明白了吗


如上所述,使用
插值器来计算旋转,并使用
视图。设置旋转
来旋转它

关于颜色,我认为使用
backgroundtinlist
作为FAB背景是可行的。但是我应该用什么来表示里面的图标呢?似乎
setColorFilter
适用于它,但它正确吗?关于
View.setRotation
,一些人声称它在旧的Android版本上不起作用,因为它会旋转阴影,但我已经测试过了,它似乎在Android 4.2上也能正常工作。确实安全吗?对于图标,您可以尝试着色(
DrawableCompat.setTint(
)可绘制(
Fa
b是一个
ImageView
,具有
getDrawable()
方法).我不知道它是否有效,但我会尝试一下,但也许setColorFilter也可以?我已经测试过了,它似乎在各种Android版本上都能正常工作,从4.2到P。为什么要投反对票?
class MainActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        val yToResetTo = (fab.layoutParams as ViewGroup.MarginLayoutParams).topMargin.toFloat()
        val argbEvaluator = ArgbEvaluator()
        fabTouchingAreaView.setOnTouchListener(object : View.OnTouchListener {
            val WHITE_COLOR = 0xffffffff.toInt()
            val RED_COLOR = 0xffff0000.toInt()
            val GREEN_COLOR = 0xff00ff00.toInt()
            var startTouchY = Float.MIN_VALUE
            var startViewY = Float.MIN_VALUE
            var maxToGoTo = Float.MIN_VALUE
            var animator: ObjectAnimator? = null

            fun updateView() {
                val newY = fab.y
                val percentDown = if (newY <= yToResetTo) 0.0f else ((newY - yToResetTo) / (maxToGoTo - yToResetTo))
                val percentUp = if (newY >= yToResetTo) 0.0f else (1.0f - (newY / yToResetTo))
                // need code here to update content
            }

            override fun onTouch(view: View, motionEvent: MotionEvent): Boolean {
                when (motionEvent.action) {
                    MotionEvent.ACTION_DOWN -> {
                        if (animator != null) {
                            animator!!.cancel()
                            animator = null
                        }
                        startTouchY = motionEvent.rawY
                        startViewY = fab.y
                        maxToGoTo = fabTouchingAreaView.height.toFloat() - fab.height
                    }
                    MotionEvent.ACTION_UP -> {
                        if (animator == null) {
                            animator = ObjectAnimator.ofFloat(fab, View.Y, yToResetTo)
                            //TODO use normal animate() when minSdk is at least 19
                            animator!!.addUpdateListener { animation -> updateView() }
                            animator!!.start()
                        }
                    }
                    MotionEvent.ACTION_MOVE -> {
                        val newY = Math.min(Math.max(startViewY + (motionEvent.rawY - startTouchY), 0.0f), maxToGoTo)
                        fab.y = newY
                        updateView()
                    }
                }
                return true
            }
        })
    }
}
                val fabBackgroundColor = when {
                    percentDown > 0f -> argbEvaluator.evaluate(percentDown, WHITE_COLOR, RED_COLOR) as Int
                    percentUp > 0f -> argbEvaluator.evaluate(percentUp, WHITE_COLOR, GREEN_COLOR) as Int
                    else -> WHITE_COLOR
                }
                val fabIconColor = when {
                    percentDown > 0f -> argbEvaluator.evaluate(percentDown, GREEN_COLOR, WHITE_COLOR) as Int
                    percentUp > 0f -> argbEvaluator.evaluate(percentUp, GREEN_COLOR, WHITE_COLOR) as Int
                    else -> GREEN_COLOR
                }
                fab.setColorFilter(fabIconColor)
                fab.backgroundTintList = ColorStateList.valueOf(fabBackgroundColor)
                fab.rotation = percentDown * 135
                Log.d("appLog", "y:" + fab.y + " percentDown:$percentDown percentUp:$percentUp " +
                        "fabBackgroundColor:${Integer.toHexString(fabBackgroundColor)} fabIconColor:${Integer.toHexString(fabIconColor)}")