Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

UNDERLABEL doesn't work on ConstraintLayout #33

Open
matiit opened this issue Jul 9, 2017 · 8 comments
Open

UNDERLABEL doesn't work on ConstraintLayout #33

matiit opened this issue Jul 9, 2017 · 8 comments
Labels

Comments

@matiit
Copy link

matiit commented Jul 9, 2017

device-2017-07-09-134358

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="[email protected]"
        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>
@thyrlian
Copy link
Owner

thyrlian commented Jul 9, 2017

Thanks for reporting, will check it later.

@thyrlian
Copy link
Owner

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.

@thyrlian thyrlian changed the title UNDERLABEL doesn't work on relative layout UNDERLABEL doesn't work on ConstraintLayout Aug 17, 2017
@thyrlian
Copy link
Owner

thyrlian commented Jan 2, 2018

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.

@thyrlian
Copy link
Owner

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);

@thyrlian
Copy link
Owner

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

@thyrlian
Copy link
Owner

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.

@Sabutori
Copy link

When will this issue be fixed?

@thyrlian
Copy link
Owner

@Sabutori probably not, at least it won't be fixed by me. As mentioned earlier, I just could not find a solution for this back in time, but also get no time to check this for the moment. Sorry for giving such a negative answer.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

3 participants