无法在ConstraintLayout.Group中的单个项目上设置可见性 [英] Cannot set visibility on individual items in a ConstraintLayout.Group

查看:144
本文介绍了无法在ConstraintLayout.Group中的单个项目上设置可见性的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个ConstraintLayout.Group定义如下:

    <android.support.constraint.Group
        android:id="@+id/someGroup"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        app:constraint_referenced_ids="
        textView1,
        textView2,
        button1" />

我将该群组的可见性从消失"更改为可见":

I change the visibility of this group from GONE to VISIBLE:

someGroup.visibility = VISIBLE

但是当我尝试通过指定该组中某个视图的可见性来覆盖它时:

But when I try to override it by specifying the visibility of one of the views in that group:

button1.visibility = GONE

...不起作用.我将此可见性记录到logcat中,并显示8 (GONE),但我仍然可以看到该视图.

...it doesn't work. I log this visibility to logcat and it says 8 (GONE), but I can still see the view.

任何想法在这里可能会发生什么?我尝试在该组上调用requestLayoutupdatePreLayout,我尝试了几次更改可见性,可见,不可见然后消失的情况.我什至重新构建了整个项目,因为一些stackoverflow回答说这可能有助于解决ConstraintLayout中的可见性问题.我还尝试了1.1.3和2.2.0-alpha版本.没事.它总是可见的.

Any ideas what might be happening here? I tried calling requestLayout and updatePreLayout on this group, I tried changing the visibility a few times, visible, invisible and then gone. I even rebuilt the whole project because some stackoverflow answer said that it might help for visiblity issues in ConstraintLayout. I also tried versions 1.1.3 and 2.2.0-alpha. Nothing worked. It's always visible.

推荐答案

更新:组内单个视图可见性的行为已更改,并在ConstraintLayout 2.0.0 beta版中报告为已修复6.请参见 ConstraintLayout 2.0.0 beta 6的错误修复.

Update: The behavior of individual view visibility within a group has been change and is reported as fixed in ConstraintLayout version 2.0.0 beta 6. See bug fixes for ConstraintLayout 2.0.0 beta 6 .

您看到的是正确的行为.将视图放置在组中时,您放弃了更改单个视图的可见性的功能.我认为机制是(由您)设置视图的可见性,然后根据组成员身份分配(由系统)该组的可见性.

You are seeing the correct behavior. When you place a view within a group, you give up the ability to change the individual view's visibility. I think the mechanics are that the view's visibility is set (by you) then the group's visibility is assigned (by the system) based upon group membership.

解决方法取决于您的需求:

The workaround is dependent upon your needs:

  1. 保留要控制的视图,以控制组外的可见性;
  2. 管理您自己的组逻辑,而忘记系统提供的组;
  3. 使用 setReferencedIds .

我认为这是常见的投诉,但我也认为不太可能解决. (恕我直言)

I think that this is a common complaint, but I also think that it is unlikely to be addressed. (IMHO)

我刚刚评论了有关此确切问题的另一个问题,因此我可以自由地在此处发布一个简单的类(尽管答案已被接受),该类将有助于管理ConstraintLayout小组.

I just commented on another question regarding this exact issue, so I have taken the liberty to post here (although the answer is already accepted) a simple class that will help manage a ConstraintLayout group.

ManagedGroup.java

/**
 * Manage a ConstraintLayout Group view membership as a view's visibility is changed. Calling
 * {@link #setVisibility(View, int)} will set a view's visibility and remove it from the group.
 * Other methods here provide explicit means to manage a group's view membership.
 * <p>
 * Usage: In XML define
 * <pre>{@code
 * <[Package].ManagedGroup
 *         android:id="@+id/group"
 *         android:layout_width="wrap_content"
 *         android:layout_height="wrap_content"
 *         android:visibility="visible"
 *         app:constraint_referenced_ids="id1,id2,id3..." />}
 * </pre>
 */
public class ManagedGroup extends Group {
    private final Set<Integer> mRemovedRefIds = new HashSet<>();

    public ManagedGroup(Context context) {
        super(context);
    }

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

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

    /**
     * Set the reference ids for the group and clear the removed id array.
     *
     * @param ids All identifiers in the group.
     */
    @Override
    public void setReferencedIds(@NonNull int[] ids) {
        super.setReferencedIds(ids);
        mRemovedRefIds.clear();
    }

    /**
     * Set visibility for  view and remove the view's id from the group.
     *
     * @param view       View for visibility change
     * @param visibility View.VISIBLE, View.INVISIBLE or View.GONE.
     */
    public void setVisibility(@NonNull View view, int visibility) {
        removeReferencedIds(view.getId());
        view.setVisibility(visibility);
    }

    /**
     * Add all removed views back into the group.
     */
    public void resetGroup() {
        setReferencedIds(getAllReferencedIds());
    }

    /**
     * Remove reference ids from the group. This is done automatically when
     * setVisibility(View view, int visibility) is called.
     *
     * @param idsToRemove All the ids to remove from the group.
     */
    public void removeReferencedIds(int... idsToRemove) {
        for (int id : idsToRemove) {
            mRemovedRefIds.add(id);
        }

        int[] refIds = getReferencedIds();
        Set<Integer> newRefIdSet = new HashSet<>();

        for (int id : refIds) {
            if (!mRemovedRefIds.contains(id)) {
                newRefIdSet.add(id);
            }
        }
        super.setReferencedIds(copySetToIntArray(newRefIdSet));
    }

    /**
     * Add reference ids to the group.
     *
     * @param idsToAdd Identifiers to add to the group.
     */
    public void addReferencedIds(int... idsToAdd) {
        for (int id : idsToAdd) {
            mRemovedRefIds.remove(id);
        }
        super.setReferencedIds(joinArrays(getReferencedIds(), idsToAdd));
    }

    /**
     * Return int[] of all ids in the group plus those removed.
     *
     * @return All current ids in group plus those removed.
     */
    @NonNull
    public int[] getAllReferencedIds() {
        return joinArrays(getReferencedIds(), copySetToIntArray(mRemovedRefIds));
    }

    @NonNull
    private int[] copySetToIntArray(Set<Integer> fromSet) {
        int[] toArray = new int[fromSet.size()];
        int i = 0;

        for (int id : fromSet) {
            toArray[i++] = id;
        }

        return toArray;
    }

    @NonNull
    private int[] joinArrays(@NonNull int[] array1, @NonNull int[] array2) {
        int[] joinedArray = new int[array1.length + array2.length];

        System.arraycopy(array1, 0, joinedArray, 0, array1.length);
        System.arraycopy(array2, 0, joinedArray, array1.length, array2.length);
        return joinedArray;
    }
}

这篇关于无法在ConstraintLayout.Group中的单个项目上设置可见性的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆