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

时间:2018-06-27 23:52:57

标签: android android-layout android-constraintlayout

我通过使用新的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>

我介绍了Group是为了控制某些布局,尽管为简单起见,我省略了所有内容。该错误的实质是引入该组阻止我将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无关。

3 个答案:

答案 0 :(得分:5)

尽管如上所述,您不能仅更改单个Group子级的可见性(为此,我发现此小部件的有用性和趣味性降低了很多),但是您始终可以设置其alpha属性。

因此,如果您不会以任何方式混淆要隐藏的视图的alpha值,则可以执行以下操作:

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

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

答案 1 :(得分:2)

我不认为这是个问题,因为根据docs,基本上就是Group的使用:

  

此类控制一组引用的窗口小部件的可见性。

也:

  

该组的可见性将应用于引用的窗口小部件。这是一种轻松隐藏/显示一组小部件而无需以编程方式维护此小部件的便捷方法。

因此,您必须在群组本身上设置可见性。我不知道您使用该组的目的是什么,因为您没有指定,但是也许您应该进行重组以更好地利用它,或者完全摆脱它。

答案 2 :(得分:0)

只需添加各种解决方案-您就可以扩展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);
                }
            }
        }
    }
}

作为参考,这是基类(组)中的代码:

  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"/>