如何通过代码为Motion Layout的ConstraintSet设置customColorValue
问题:动态修改MotionLayout中ConstraintSet的customColorValue
我在MotionLayout中用以下MotionScene实现了TextView文本颜色从黑色到绿色的动画:
<MotionScene xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto"> <Transition app:constraintSetEnd="@id/end" app:constraintSetStart="@+id/start" app:autoTransition="animateToEnd" app:duration="1000"/> <ConstraintSet android:id="@+id/start"> <Constraint android:id="@+id/fab" android:layout_width="1dp" android:layout_height="1dp" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintStart_toStartOf="parent" /> <Constraint android:id="@+id/statusResult2"> <CustomAttribute app:attributeName="textColor" app:customColorValue="#000000"/> </Constraint> </ConstraintSet> <ConstraintSet android:id="@+id/end"> <Constraint android:id="@id/fab" android:layout_width="wrap_content" android:layout_height="wrap_content" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintEnd_toEndOf="parent" /> <Constraint android:id="@+id/statusResult2"> <CustomAttribute app:attributeName="textColor" app:customColorValue="#008000"/> </Constraint> </ConstraintSet> </MotionScene>
现在希望在Activity中根据条件,通过代码动态设置@id/end的ConstraintSet里的app:customColorValue。尝试了以下代码但出现编译器错误:
binding.motionLayout.getConstraintSet(R.id.end).apply { this.customAttributeSet.put("customColorValue", "#008000") }
编译器提示该字段需要ConstraintAttribute而非字符串,不清楚如何处理。我的Activity代码如下:
class DetailActivity : AppCompatActivity() { private lateinit var binding: ActivityDetailBinding private lateinit var notificationManager: NotificationManager override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) binding = ActivityDetailBinding.inflate(layoutInflater) setContentView(binding.root) setSupportActionBar(binding.toolbar) supportActionBar?.title = "Download Result Details" notificationManager = getSystemService(NotificationManager::class.java) as NotificationManager binding.fileNameResult.text = intent.getStringExtra("fileName") if(intent.getStringExtra("result").equals(DownloadResults.PASSED.description)){ binding.statusResult.text = DownloadResults.PASSED.description } else { binding.statusResult.text = DownloadResults.FAILED.description binding.statusResult.setTextColor(Color.RED) } notificationManager.cancel() binding.fab.setOnClickListener { Intent(this, MainActivity::class.java).apply{ this.flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK startActivity(this) } } // binding.motionLayout.getConstraintSet(R.id.end).apply { // this.customAttributeSet.put("customColorValue", "#008000") // } } }
解决方案
要动态修改ConstraintSet中的自定义颜色属性,不能直接操作customAttributeSet,需要通过setCustomAttribute方法创建并设置ConstraintAttribute,具体步骤如下:
代码实现
将你注释掉的代码替换为以下内容:
binding.motionLayout.getConstraintSet(R.id.end).apply { // 针对目标View设置自定义textColor属性 setCustomAttribute( R.id.statusResult2, "textColor", ConstraintAttribute.AttributeType.COLOR, // 根据下载结果动态切换颜色 if (intent.getStringExtra("result").equals(DownloadResults.PASSED.description)) { Color.GREEN } else { Color.RED } ) // 通知MotionLayout更新修改后的ConstraintSet binding.motionLayout.updateState(R.id.end, this) }
关键说明
setCustomAttribute需要四个参数:目标View的ID、属性名称、属性类型(此处为COLOR)、颜色的int值(推荐用Color类常量,或带alpha通道的十六进制值如0xFF008000)- 必须调用
updateState方法,让MotionLayout应用修改后的ConstraintSet,否则动画不会使用新的颜色值 - 颜色值需传入int类型,不能直接传字符串格式的颜色码
内容的提问来源于stack exchange,提问作者Wade Byron Profe
相关产品推荐
相关产品推荐

