ConstraintLayout 中的组阻止设置 ProgressBar 可见性

Group in ConstraintLayout prevents setting ProgressBar visibility

我正在通过使用新的 ConstraintLayout (1.1.2) 来展平我的布局,但是我无法再控制 ProgressBar 在组中时的可见性。这是我的布局 XML 文件的最简单版本,它重现了该问题:

    <android.support.constraint.ConstraintLayout
        android:layout_width="wrap_content"
        android:layout_height="wrap_content">

        <!-- This group prevents me from hiding ProgressBar -->
        <android.support.constraint.Group
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            app:constraint_referenced_ids="imageLoadingSpinner" />

        <ProgressBar
            android:id="@+id/imageLoadingSpinner"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content" />

    </android.support.constraint.ConstraintLayout>

我引入了组以控制某些布局,但为了简单起见,我将所有内容都省略了。该错误的本质是引入组阻止我将 ProgressBar 的可见性设置为 GONE

以下代码不再隐藏 ProgressBar:

    find(R.id.imageLoadingSpinner).setVisibility(GONE);

明确一点,如果我删除组,如下所示,我可以将 ProgressBar 的可见性设置为 GONE:

    <android.support.constraint.ConstraintLayout
        android:layout_width="wrap_content"
        android:layout_height="wrap_content">

        <!-- Commenting out this group allows me to hide ProgressBar -->
        <!--<android.support.constraint.Group-->
            <!--android:layout_width="wrap_content"-->
            <!--android:layout_height="wrap_content"-->
            <!--app:constraint_referenced_ids="imageLoadingSpinner" />-->

        <ProgressBar
            android:id="@+id/imageLoadingSpinner"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content" />

    </android.support.constraint.ConstraintLayout>

我找不到有关此问题的任何信息。 ProgressBar visibility issue 无关。

我认为这不是问题,因为根据 docs:

,本质上这是 Group 的使用

This class controls the visibility of a set of referenced widgets.

另外:

The visibility of the group will be applied to the referenced widgets. It's a convenient way to easily hide/show a set of widgets without having to maintain this set programmatically.

因此您必须设置组本身的可见性。我不知道你用这个组做什么,因为你没有指定,但也许你应该重组以更好地利用它,或者完全摆脱它。

虽然如前所述,您不能仅更改一个组的子项的可见性(为此我发现此小部件的帮助和乐趣要小得多),但您始终可以设置它的 alpha 属性.

因此,如果您不想以任何方式弄乱要隐藏的视图的 alpha 值,则只需执行以下操作:

find(R.id.imageLoadingSpinner).setAlpha(0);

而且我找不到不这样做的理由,除了视图可能仍会被渲染,然后所有渲染像素将被转换为 0-alpha,从而变得无形的浪费这一事实几个时钟周期,但在大多数情况下,将其视为问题是夸张的。

只是为了增加解决方案的多样性 - 您可以扩展 Group 并使其表现得像您期望的那样。如果您经常使用组并且您希望在可见性方面有正常的父子行为,这会更方便一些。

public class LayoutGroup extends Group {
    public LayoutGroup(Context context) {
        super(context);
    }

    public LayoutGroup(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    public LayoutGroup(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }

    @Override
    public void updatePreLayout(ConstraintLayout container) {
        int visibility = this.getVisibility();
        float elevation = 0.0F;
        if (Build.VERSION.SDK_INT >= 21) {
            elevation = this.getElevation();
        }

        for(int i = 0; i < this.mCount; ++i) {
            int id = this.mIds[i];
            View view = container.getViewById(id);
            if (view != null) {
                // If the group is visible, let the child control visibility
                view.setVisibility(visibility == VISIBLE ? view.getVisibility() : visibility);
                if (elevation > 0.0F && Build.VERSION.SDK_INT >= 21) {
                    view.setElevation(elevation);
                }
            }
        }
    }
}

作为参考,这里是来自基地class(组)的代码:

  for(int i = 0; i < this.mCount; ++i) {
        int id = this.mIds[i];
        View view = container.getViewById(id);
        if (view != null) {
            view.setVisibility(visibility);
            if (elevation > 0.0F && VERSION.SDK_INT >= 21) {
                view.setElevation(elevation);
            }
        }
    }

那么在你的布局文件中当然要使用你自己的组件:

   <yourpackage.LayoutGroup
            android:id="@+id/group_id"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            app:constraint_referenced_ids="view1,view2,view3"/>