constraintlayout
constraintlayout copied to clipboard
Flow visibility broken since 2.1.0
Setting visibility on a Flow using 2.0.4 works fine. As soon as I update to 2.1.0 it breaks.
Most likely be caused by https://github.com/androidx/constraintlayout/pull/258
Note: I update a ConstraintSet (setting bias) during runtime for different views of the container - seems like this update is applying visibility to not affected siblings
added a sample project here: https://github.com/chriswiesner/ConstraintLayoutVisibilityBug
The issue is still reproducible in the 2.1.4 version.
An explanation:
- For example, we have a
Flow
of views and one of the referenced views isGONE
for some reason, then we want to change a constraint of a view that is not referenced inFlow
, e.g. vertical bias, but maintain all constraints of the initial state.
ConstraintSet().apply {
clone(constraintLayot)
setVerticalBias(viewToChangeId, 0.5f)
applyTo(constraintLayot)
}
- ConstraintSet starts applying constraints, it takes all children and set their params, but at the end of
constraintSet.applyToInternal()
we have the block that invokes helpers to modifyView
(see code below). SinceFlow
is aConstraintHelper
then insideapplyLayoutFeatures()
visibility of eachView
is erased byFlow
visibility.
// ConstraintSet#applyToInternally
for (int i = 0; i < count; i++) {
View view = constraintLayout.getChildAt(i);
if (view instanceof ConstraintHelper) {
ConstraintHelper constraintHelper = (ConstraintHelper) view;
constraintHelper.applyLayoutFeaturesInConstraintSet(constraintLayout);
}
}
// ConstraintHelper#applyLayoutFeatures
int visibility = getVisibility();
float elevation = 0;
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.LOLLIPOP) {
elevation = getElevation();
}
for (int i = 0; i < mCount; i++) {
int id = mIds[i];
View view = container.getViewById(id);
if (view != null) {
view.setVisibility(visibility); // erasing original visibility
if (elevation > 0 && android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.LOLLIPOP) {
view.setTranslationZ(view.getTranslationZ() + elevation);
}
}
}
In my opinion, this kind of behavior should not be legit because Flow
is about positioning and if we want to change the visibility of all referenced View
then we should use Group
instead.