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版中报告为已修复。看
你看到了正确的行为。在组中放置视图时,将放弃更改单个视图可见性的功能。我认为机制是视图的可见性(由您设置),然后根据组成员资格(由系统)指定组的可见性 解决方案取决于您的需要:
我刚刚就关于这个问题的另一个问题发表了评论,因此我冒昧地在这里发布了一个简单的类(尽管答案已经被接受),它将帮助管理
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;
}
}