Android 使用“合并”从布局创建约束集

Android 使用“合并”从布局创建约束集,android,kotlin,android-constraintlayout,Android,Kotlin,Android Constraintlayout,我想做一个从一个约束集到另一个约束集的Changebounds()动画 通常,我通过创建两个约束集来实现这一点: private val originalState = ConstraintSet().apply { clone(context, R.layout.layout_meta_syntactic) } private val expandedState = ConstraintSet().apply { clone(context, R.layout.layout_

我想做一个从一个约束集到另一个约束集的
Changebounds()
动画

通常,我通过创建两个约束集来实现这一点:

private val originalState = ConstraintSet().apply {
    clone(context, R.layout.layout_meta_syntactic)
}

private val expandedState = ConstraintSet().apply {
    clone(context, R.layout.layout_meta_syntactic)
    // Change some constraints
    connect(
        R.id.button, ConstraintSet.END,
        R.id.foo_text, ConstraintSet.START
    )
}
并通过以下方式来回设置动画:

TransitionManager.beginDelayedTransition(id_of_my_component_in_fragment, transition)
originalState.applyTo(id_of_my_component_in_fragment)
但是现在,我要从中克隆的布局中有一个
标记。合并布局是扩展ConstraintLayout的复合组件的基础

复合成分:

class MyCompoundView : ConstraintLayout {

// Omissions
inflate(context, R.layout.layout_meta_syntactic, this)
充气:

<merge xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/some_id"
    tools:parentTag="androidx.constraintlayout.widget.ConstraintLayout">

    // Views 

//观点
尝试以编程方式将布局克隆到约束集时,我得到:

 Caused by: android.view.InflateException: Binary XML file line #2: <merge /> can be used only with a valid ViewGroup root and attachToRoot=true
 Caused by: android.view.InflateException: <merge /> can be used only with a valid ViewGroup root and attachToRoot=true
原因:android.view.InflateException:二进制XML文件行#2:只能与有效的ViewGroup根一起使用,且attachToRoot=true
原因:android.view.InflateException:只能与有效的ViewGroup根一起使用,且attachToRoot=true
如何从这样的布局创建约束集?

您有两个选项:

  • 使用
    ConstraintLayout
    根目录创建另一个(虚拟)布局文件,该文件使用
    include
    标记保存布局引用
  • 从自定义视图的新实例克隆布局参数:
    ConstraintSet.Clone(context,MyCompoundView(context))

  • ConstraintSet.clone(context,layoutRes)
    实际上是相当粗糙的,它本质上是从提供的布局文件(包括所有子视图)中展开新的
    ConstraintLayout
    ,然后解析其布局参数以构建
    ConstraintSet
    。解决方案是克隆作为ConstraintLayout的复合组件

    class MyCompoundView : ConstraintLayout {
    
        // make sure to clone after inflating the layout to the component
    
        originalState = ConstraintSet().apply {
            clone(this@MyCompoundView)
        }
    
        expandedState = ConstraintSet().apply {
            clone(this@MyCompoundView)
            // Change some constraints
             connect(
                 R.id.button, ConstraintSet.END,
                 R.id.foo_text, ConstraintSet.START
            )
        }
    }
    

    是的,我注意到在调试时,断点会触发每个克隆(layoutId)。但是有没有更好的方法呢?我是否通过克隆膨胀的约束布局来绕过它?@Adam yes,如果您已经有膨胀的
    ConstraintLayout
    实例,它将通过迭代子项及其布局参数来构建集合。