UNDERLABEL doesn't work on ConstraintLayout
matiit opened this issue · 8 comments
For given layout:
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="anddev.mat.pckplace.CreateAccount">
<EditText
android:id="@+id/email"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:ems="10"
android:inputType="textEmailAddress"
android:text="example@domain.com"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<EditText
android:id="@+id/password"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="16dp"
android:ems="10"
android:inputType="textPassword"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toBottomOf="@+id/email" />
<Button
android:id="@+id/joinButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="16dp"
android:text="Join"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toBottomOf="@+id/password" />
<ProgressBar
android:id="@+id/progressBar"
style="?android:attr/progressBarStyle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.185" />
</android.support.constraint.ConstraintLayout>
Thanks for reporting, will check it later.
Just tried with your layout, the UNDERLABEL
validation doesn't work properly indeed. I think the problem is because of ConstraintLayout
. I'll try to find out a solution and meanwhile update the demo project with ConstraintLayout. Thanks again.
Apart from copying the LayoutParams
, I also tried to copy the ConstraintSet
for each view inside the ConstraintLayout
(and then later apply them to corresponding new container view). Unfortunately this approach doesn't work. After checking the source code of ConstraintSet
, I found the cause:
public class ConstraintSet {
private HashMap<Integer, ConstraintSet.Constraint> mConstraints = new HashMap();
...
public void clone(ConstraintLayout constraintLayout) {
int count = constraintLayout.getChildCount();
this.mConstraints.clear();
for(int i = 0; i < count; ++i) {
View view = constraintLayout.getChildAt(i);
LayoutParams param = (LayoutParams)view.getLayoutParams();
int id = view.getId();
if(!this.mConstraints.containsKey(Integer.valueOf(id))) {
this.mConstraints.put(Integer.valueOf(id), new ConstraintSet.Constraint());
}
...
The relationship HashMap mConstraints
holds each view's id as the key, that's why simply copying attributes doesn't work. The constraint is bound with view id, always refer to view id at creation, not transferable.
Tried to hack by setting new container's id to EditText
's id, then giving EditText
a new id, assuming this would hand over all constraints from EditText
to its new container parent. But unfortunately it doesn't work either :(
int idOfEditText = editText.getId();
editText.setId(View.generateViewId());
newContainer.setId(idOfEditText);
The private member mConstraintSet
of ConstraintLayout
is also null:
Field fieldConstraintSet = ((ConstraintLayout) parent).getClass().getDeclaredField("mConstraintSet");
fieldConstraintSet.setAccessible(true);
ConstraintSet constraintSet = (ConstraintSet) fieldConstraintSet.get(parent);
// constraintSet is null here
// the reason is when init, attr != styleable.ConstraintLayout_Layout_constraintSet
Sorry @matiit, finally I gave up - spent too much time on it but could not find a solution, it's way too complicated.
Created and merged a PR: #50
In this PR, when the application tries to use UNDERLABEL
for ConstraintLayout
, a UnsupportedLayoutException
will be thrown with message:
UnderlabelValidator doesn't support ConstraintLayout, please use TextInputLayoutValidator or other any other validator.
And in the demo project, I changed the TextInputLayout
validation style's layout to ConstraintLayout
, to show how it works.
I'll keep this issue open, won't fix for now, but will still look for a solution in the future. I'm really sorry for that and thank you very much for reporting this issue.
When will this issue be fixed?