无法在ConstraintLayout.Group中的单个项目上设置可见性 [英] Cannot set visibility on individual items in a 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.
任何想法在这里可能会发生什么?我尝试在该组上调用requestLayout
和updatePreLayout
,我尝试了几次更改可见性,可见,不可见然后消失的情况.我什至重新构建了整个项目,因为一些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:
- 保留要控制的视图,以控制组外的可见性;
- 管理您自己的组逻辑,而忘记系统提供的组;
- 使用 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屋!