【问题标题】:Creating constraintset from layout with merge使用合并从布局创建约束集
【发布时间】:2019-04-15 03:32:35
【问题描述】:

我想做一个从一个约束集到另一个约束集的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)

但现在我在要从中克隆的布局中遇到了<merge> 标签。合并布局是扩展 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 kotlin android-constraintlayout


    【解决方案1】:

    你有两个选择:

    1. 使用ConstraintLayout 根创建另一个(虚拟)布局文件,其中包含带有include 标记的布局引用。
    2. 从自定义视图的新实例中克隆布局参数:ConstraintSet.clone(context, MyCompoundView(context))

    ConstraintSet.clone(context, layoutRes) 实际上在引擎盖下相当粗糙 (source),它本质上是从提供的布局文件中膨胀新的 ConstraintLayout,包括所有子视图,然后解析它们的布局参数以构建 ConstraintSet

    【讨论】:

    • 是的,我注意到调试时很粗糙,每个克隆(layoutId)都会触发断点。但是有没有更好的方法呢?我是否可以通过克隆膨胀的约束布局来解决它?
    • @Adam 是的,如果您已经有一个膨胀的ConstraintLayout 实例,它会通过迭代子项及其布局参数来构建集合。
    【解决方案2】:

    解决方案是克隆复合组件,它是一个 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
            )
        }
    }
    

    【讨论】:

      猜你喜欢
      • 2021-06-27
      • 2018-11-04
      • 1970-01-01
      • 2012-10-01
      • 2015-07-20
      • 1970-01-01
      • 2020-06-14
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多