我有一个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" />
我将该群组的可见性从“消失”更改为“可见”:
someGroup.visibility = VISIBLE
但是当我尝试通过指定该组中某个视图的可见性来覆盖它时:
button1.visibility = GONE
...不起作用。我将此可见性记录到logcat中,并说8 (GONE)
,但我仍然可以看到该视图。
任何想法在这里会发生什么?我尝试在此群组上调用requestLayout
和updatePreLayout
,并尝试更改可见性几次,可见,不可见,然后消失。我什至重新构建了整个项目,因为一些stackoverflow回答说这可能有助于解决ConstraintLayout中的可见性问题。我还尝试了1.1.3和2.2.0-alpha版本。没事。它总是可见的。
答案 0 :(得分:7)
您看到的是正确的行为。将视图放置在组中时,您放弃了更改单个视图的可见性的功能。我认为机制是(由您)设置视图的可见性,然后根据组成员身份分配(由系统)组的可见性。
解决方法取决于您的需求:
我认为这是常见的投诉,但我也认为不太可能解决。 (恕我直言)
我刚刚评论了有关此确切问题的另一个问题,因此我可以自由地在此处发布一个简单的类(尽管答案已经被接受),该类将有助于管理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;
}
}