ConstraintSet简介和作用
ConstraintSet是ConstraintLayout约束布局中所有组件的属性集合,只能应用于约束布局,约束布局中的组件会按照ConstraintSet中的属性重新绘制。
可以利用ConstraintSet动态设置组件的约束属性,也可以用来实现关键帧动画。
ConstraintSet的使用
创建和初始化
private val endConstraintSet by lazy { ConstraintSet() }
拷贝约束属性
可以通过clone()拷贝约束集数据,该函数遍历传入布局的子view,一一复制他们的属性:
//从布局文件中拷贝,填入Context和目标布局id,最终调用clone(ConstraintLayout constraintLayout):
public void clone(Context context, int constraintLayoutId) {...}
//从约束集中拷贝:
public void clone(ConstraintSet set) {...}
//从约束布局中拷贝:
public void clone(ConstraintLayout constraintLayout) {...}
//直接从约束中拷贝:
public void clone(Constraints constraints) {...}
加载约束属性
也可以通过load()加载约束集数据:
//resourceId为目标布局文件id
public void load(Context context, int resourceId)
public void load(Context context, XmlPullParser parser)
修改属性值
通过setXXX(int viewId,T... attr)设置约束集中单个组件的属性,根据具体函数在变长参数位置填入对应属性值。
通过源码可以看到,大部分组件的属性都是无法获取到的 ,只有少数属性width、heigh、visibility可以通过getXXX(int viewId)获取。
约束集的应用
约束集中的属性分为约束属性和非约束属性,可以选择应用哪一种属性。
-
应用所有属性到目标布局:
applyTo(ConstraintLayout constraintLayout) -
只应用约束属性:
applyToWithoutCustom(ConstraintLayout constraintLayout) -
应用非约束属性:
applyCustomAttributes(ConstraintLayout constraintLayout) -
将所有属性应用到某一个组件:
applyToLayoutParams(int id, LayoutParams layoutParams),参数填入该组件的id和LayoutParams
ConstraintSet实现关键帧动画
关键帧动画根据动画的初始状态和结束状态渲染,需要分别写出初始状态和结束状态的布局文件。先将布局设置为初始状态,利用ConstraintSet复制最终状态的属性,再将这个ConstraintSet应用到布局。中间通过TransitionManager渲染动画,这样就能实现关键帧动画。
代码示例:
//创建约束集
private val endConstraintSet by lazy { ConstraintSet() }
private val startConstraintSet by lazy { ConstraintSet() }
//动画时间2000ms
private val mTransition by lazy { AutoTransition().apply { setDuration(2000) } }
//克隆属性
private fun initAnimate() {
startConstraintSet.clone(this, R.layout.activity_test_start)
endConstraintSet.clone(this, R.layout.activity_test_end)
}
private var animated = false
private fun animatekeyFrame() {
//constraintSet表示下一个状态的约束集
val constraintSet = if (animated) startConstraintSet else endConstraintSet
//渲染动画
TransitionManager.beginDelayedTransition(viewBinding.root, mTransition)
//将约束集应用到根布局
constraintSet.applyTo(viewBinding.root)
animated = !animated
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_test_start)
//点击按钮切换页面状态
viewBinding.testBtn.setOnClickListener {
animatekeyFrame()
}
}
初始状态:
结束状态:
动画过程: