Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/179.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/oop/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Android 无法设置ConstraintLayout.Group中单个项目的可见性_Android_Android Layout_Android Constraintlayout - Fatal编程技术网

Android 无法设置ConstraintLayout.Group中单个项目的可见性

Android 无法设置ConstraintLayout.Group中单个项目的可见性,android,android-layout,android-constraintlayout,Android,Android Layout,Android Constraintlayout,我有一个ConstraintLayout.Group定义如下: <android.support.constraint.Group android:id="@+id/someGroup" android:layout_width="wrap_content" android:layout_height="wrap_content" app:constraint_referenced_ids=" text

我有一个
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" />
但当我试图通过指定该组中某个视图的可见性来覆盖它时:

button1.visibility = GONE
…它不起作用。我将此可见性记录到logcat,它显示
8(已消失)
,但我仍然可以看到视图


你知道这里会发生什么吗?我尝试在这个组上调用
requestLayout
updatePreLayout
,我尝试了几次更改可见性,可见、不可见,然后消失。我甚至重建了整个项目,因为一些stackoverflow回答说它可能有助于解决ConstraintLayout中的可视性问题。我还尝试了版本1.1.3和2.2.0-alpha。什么都没用。它始终可见。

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


你看到了正确的行为。在组中放置视图时,将放弃更改单个视图可见性的功能。我认为机制是视图的可见性(由您设置),然后根据组成员资格(由系统)指定组的可见性

解决方案取决于您的需要:

  • 将要控制其可见性的视图保留在组之外
  • 管理您自己的组逻辑,忘记系统提供的组
  • 使用管理组成员资格
  • 我认为这是一个常见的投诉,但我也认为这不太可能得到解决。(IMHO)


    我刚刚就关于这个问题的另一个问题发表了评论,因此我冒昧地在这里发布了一个简单的类(尽管答案已经被接受),它将帮助管理
    ConstraintLayout

    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组视图成员资格。使命感
    *{@link#setVisibility(View,int)}将设置视图的可见性并将其从组中删除。
    *这里的其他方法提供了管理组的视图成员身份的显式方法。
    *
    *用法:在XML中定义
    *{@code
    * }
    * 
    */
    公共类ManagedGroup扩展组{
    私有最终集mRemovedRefIds=new HashSet();
    公共ManagedGroup(上下文){
    超级(上下文);
    }
    公共ManagedGroup(上下文、属性集属性){
    超级(上下文,attrs);
    }
    公共ManagedGroup(上下文上下文、属性集属性、int-defStyleAttr){
    super(上下文、attrs、defStyleAttr);
    }
    /**
    *设置组的参考id并清除已删除的id数组。
    *
    *@param标识组中的所有标识符。
    */
    @凌驾
    public void setReferencedIds(@NonNull int[]ids){
    super.setReferencedIds(id);
    mRemovedRefIds.clear();
    }
    /**
    *设置视图的可见性并从组中删除视图的id。
    *
    *@param视图用于可见性更改
    *@param visibility View.VISIBLE、View.INVISIBLE或View.GONE。
    */
    公共void setVisibility(@NonNull视图,int可见性){
    RemoveReferencedId(view.getId());
    视图。设置可见性(可见性);
    }
    /**
    *将所有删除的视图重新添加到组中。
    */
    公共组(){
    setReferencedId(getAllReferencedId());
    }
    /**
    *从组中删除引用ID。当
    *调用setVisibility(视图,int visibility)。
    *
    *@param ids删除要从组中删除的所有ID。
    */
    public void removeReferencedIds(int…idsToRemove){
    用于(int-id:idsToRemove){
    mRemovedRefIds.add(id);
    }
    int[]refIds=getReferencedIds();
    Set newRefIdSet=newhashset();
    for(int-id:refIds){
    如果(!mRemovedRefIds.contains(id)){
    newRefIdSet.add(id);
    }
    }
    super.setReferencedId(copySetToIntArray(newRefIdSet));
    }
    /**
    *将引用ID添加到组中。
    *
    *@param idsToAdd要添加到组中的标识符。
    */
    public void addReferencedIds(int…idsToAdd){
    用于(int-id:idsToAdd){
    mRemovedRefIds.remove(id);
    }
    setReferencedId(joinArrays(getReferencedId(),idsToAdd));
    }
    /**
    *返回组中所有ID加上已删除ID的int[]。
    *
    *@返回组中的所有当前ID以及已删除的ID。
    */
    @非空
    public int[]GetAllReferencedId(){
    返回JoinArray(getReferencedId(),CopySetToInArray(mRemovedRefIds));
    }
    @非空
    私有int[]copySetToIntArray(从集合设置){
    int[]toArray=new int[fromSet.size()];
    int i=0;
    for(int-id:fromSet){
    toArray[i++]=id;
    }
    返回阵列;
    }
    @非空
    私有int[]joinArrays(@NonNull int[]array1,@NonNull int[]array2){
    int[]joinedaray=新int[array1.length+array2.length];
    System.arraycopy(array1,0,joinedArray,0,array1.length);
    System.arraycopy(array2,0,joinedArray,array1.length,array2.length);
    返回联合阵列;
    }
    }
    
    我担心这可能就是答案。让我等几天,如果没有人回复任何不同的内容,我会标记为正确。没错。这是一个相当愚蠢的API。将组指定给视图并不意味着他们希望通过视图唯一地控制可见性。我不相信谷歌真的是这样设计的,并认为这是一个好主意。ConstraintLayout 2.0.0 beta 6允许为单个视图设置可见性,但只有在以编程方式设置可见性时才有效
    /**
     * 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;
        }
    }