无法在约束组上设置可见性

43

当我尝试在按钮点击时设置组的可见性时,它不会影响视图的可见性。使用com.android.support.constraint:constraint-layout:1.1.0-beta4。我已经尝试了逐个元素地进行设置,没有问题,但组无法成功。

我的MainActivity.kt

private fun toggleLoginUI(show: Boolean) {
    if (show) {
        group.visibility = VISIBLE
    } else {
        group.visibility = INVISIBLE
    }
}

fun onClick(view: View) {
    when (view.id) {
        R.id.button -> toggleLoginUI(true)
        R.id.button4 -> toggleLoginUI(false)
    }
}

我的 activity_main.xml

    <android.support.constraint.ConstraintLayout..

            <TextView
                android:id="@+id/textView"
... />

            <TextView
                android:id="@+id/textView2"
... />

            <Button
                android:id="@+id/button"
.../>

            <Button
                android:id="@+id/button4"
... />


            <android.support.constraint.Group
                android:id="@+id/group"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:visibility="visible"
                app:constraint_referenced_ids="textView,textView2" />
            </android.support.constraint.ConstraintLayout>

请查看此链接:https://dev59.com/q1cP5IYBdhLWcg3wa5M3 - Hemant Parmar
有什么问题,请提供日志。 - Divyesh Kalotra
日志中没有错误,只是它什么也没做。 - SS2095
一直在盯着屏幕想要解决这个问题。 - Rohit Sharma
6个回答

40

更新:这个问题在 ConstraintLayout 版本 2.0.0 beta 6 中已被修复。请参见 ConstraintLayout 2.0.0 beta 6 的 bug 修复



我认为这看起来像是一个 bug。使用 GONE 可以生效,但 INVISIBLE 却不行,而我认为它应该可以。如果没有人能够指出我的想法错在了哪里的话,这可能值得一份 bug 报告。(我正在使用 constraint-layout:1.1.0-beta4。)

与此同时,这里有一个解决方法,它会显式地检索组内的 ID,并设置每个检索到的视图的可见性。

在 MainActivity.kt 内部

private fun toggleLoginUI(show: Boolean) {
    if (show) {
        setGroupVisibility(mLayout, group, Group.VISIBLE)
    } else {
        setGroupVisibility(mLayout, group, Group.INVISIBLE)
    }
}

private fun setGroupVisibility(layout: ConstraintLayout, group: Group, visibility: Int) {
    val refIds = group.referencedIds
    for (id in refIds) {
        layout.findViewById<View>(id).visibility = visibility
    }
}

mLayoutConstraintLayout

更新:这里是另一个解决方法,利用了将视图从GONE到可见状态的切换能够按预期执行的事实:

private fun toggleLoginUI(show: Boolean) {
    if (show) {
        group.visibility = GONE
        group.visibility = VISIBLE
    } else {
        group.visibility = GONE
        group.visibility = INVISIBLE
    }
}

那个方法可以工作,但我希望有一种不需要循环遍历元素的方式。感谢您的回答,希望问题能够得到解决。 - SS2095
如果这是一个错误,那么您将不得不等待未来的版本。(我认为这是一个错误。)如果您需要该功能,这是在过渡期内可以做的最好的事情。 - Cheticamp
有人报告了那个 bug 并且有链接吗? - Torsten Grote
1
@TorstenGrote 也许可以看一下这个链接:https://issuetracker.google.com/issues/117485026?我还看到了一个关于`ConstraintLayout` 2.0“Layer”功能的参考,可能会有所帮助。 - Cheticamp
我之前提了一个问题,与@Cheticamp一致,认为这是Group类中的一个错误: https://issuetracker.google.com/issues/130524019 - Julien Arzul

33

在将 Group 的可见性更改为 View.INVISIBLE 后,您也可以直接调用 requestLayout 方法。

fun makeGroupInvisible(group: Group) {
    group.visibility = View.INVISIBLE
    group.requestLayout()
}

问题在于android.support.constraint.GroupConstraintLayoutonMeasure方法中调用了updatePreLayout方法来更新其成员的可见性。


2
谢谢,花了两天时间才找到那个'requestLayout()'的解决方法 <3 - Mayeul sgc
谢谢!这对我有用,但这是否可以被视为约束布局的一个 bug?在每次可见性更改后调用 requestLayout() 似乎不太正常。 - Lee Boon Kong
group.requestLayout() 对我也起作用了。那一定是个 bug。 - DannyP

6

android.support.constraint.Group有一个公共方法。

 public void updatePreLayout(ConstraintLayout container) {
   ...
 }

更新子元素可见性的方法,因此调用该方法会更新其子元素的可见性。
dataGroup.visibility = if (visible) View.VISIBLE else View.INVISIBLE
dataGroup.updatePreLayout(root)

对我有用

这个答案很简单,可行,并且使用了图书馆提供的方法。这应该是正确的答案。 - Nicolás Vera

1
我有相同的问题,上面的方法都没有帮助。我的解决方案是在约束集内使用setVisibility(viewId, ConstraintSet.VISIBLE),并将其应用于ConstraintLayout视图。
例如:
myContstraintSet.apply {
    setVisibility(firstGroup.id, ConstraintSet.VISIBLE)
    setVisibility(secondGroup.id, ConstraintSet.GONE)

    connect(oneView.id, ConstraintSet.BOTTOM, R.id.secondView, ConstraintSet.TOP)
    clear(anotherView.id, ConstraintSet.TOP)
}
myContstraintSet.applyTo(myConstraintLayout)

0

只需添加以下代码即可更改它。 这样它就可以显示出来了。

group.visibility=ConstraintLayout.GONE

3
我不同意这个答案,这个问题特别涉及使用 View.INVISIBLE。使用 ConstraintLayout.GONE 与使用 View.GONE 是相同的,它是一种不同类型的可见性设置方式,同样有效。 - filipproch

-1

只需清理您的项目或重新构建您的项目


这似乎没有道理,但它确实是解决方法。显然,组相关的某些内容存在缺陷,很可能与Android Studio有关。 - Richard Le Mesurier
这对我没有帮助。 - Hanako
请分享您的代码,以便我们理解您的问题。 - Sushant Garg

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接