1

I have a ConstraintLayout with a TextView and EditText inside. The TextView is on the left, and when the EditText gains focus, I want the TextView to change its TextSize and move to the right. When it loses focus, I want to reverse that.

This is the Layout:

<androidx.constraintlayout.widget.ConstraintLayout
    android:id="@+id/custom_edit_text_constraint_layout"
    xmlns:tools="http://schemas.android.com/tools" 
    xmlns:android="http://schemas.android.com/apk/res/android" 
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
>

    <EditText
            android:id="@+id/custom_edit_text_text_field"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            app:layout_constraintTop_toTopOf="parent"
            app:layout_constraintBottom_toBottomOf="parent"
            android:paddingLeft="@dimen/custom_edittext_def_hint_margin"
            android:paddingStart="@dimen/custom_edittext_def_hint_margin"
            tools:ignore="RtlSymmetry"
    />

    <TextView
            android:id="@+id/custom_edit_text_hint"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            app:layout_constraintLeft_toLeftOf="parent"
            app:layout_constraintTop_toTopOf="parent"
            app:layout_constraintBottom_toBottomOf="parent"
            android:layout_marginLeft="@dimen/custom_edittext_def_hint_margin"
            android:layout_marginStart="@dimen/custom_edittext_def_hint_margin"/>

</androidx.constraintlayout.widget.ConstraintLayout>

And this is the code (If I forgot any important parts I can edit it):

hint = findViewById(R.id.custom_edit_text_hint);    //TextView
textField = findViewById(R.id.custom_edit_text_text_field);    //EditText
    textField.setOnFocusChangeListener(new OnFocusChangeListener() {
        @Override
        public void onFocusChange(View v, boolean hasFocus) {
            if(hasFocus) {
                focusHint();
            } else {
                unfocusHint();
            }
        }
    });

private void focusHint() {
    hint.setTextSize(hintSizeFocused);
    hint.setTextColor(hintColorFocused);
    moveHintToRight();
}

private void unfocusHint() {
    hint.setTextColor(hintColor);
    if(textField.getText().toString().isEmpty()) {
        hint.setTextSize(hintSize);
        moveHintToLeft();
    }
}

private void moveHintToRight() {
    int horizontalDistance = textField.getWidth() - hint.getRight() - dpToPx(HINT_MARGIN_SIDE);
    TranslateAnimation anim = new TranslateAnimation(0, horizontalDistance, 0, 0);
    anim.setDuration(ANIMATION_DURATION);
    anim.setAnimationListener(new Animation.AnimationListener() {
        @Override
        public void onAnimationStart(Animation animation) {}

        @Override
        public void onAnimationEnd(Animation animation) {
            ConstraintLayout l = findViewById(R.id.custom_edit_text_constraint_layout);
            ConstraintSet set = new ConstraintSet();
            set.clone(l);
            set.clear(R.id.custom_edit_text_hint, ConstraintSet.LEFT);
            set.connect(R.id.custom_edit_text_hint, ConstraintSet.RIGHT, R.id.custom_edit_text_constraint_layout, ConstraintSet.RIGHT, dpToPx(HINT_MARGIN_SIDE));
            set.applyTo(l);
        }

        @Override
        public void onAnimationRepeat(Animation animation) {}
    });
    hint.startAnimation(anim);
}

private void moveHintToLeft() {
    int horizontalDistance = - hint.getLeft() + dpToPx(HINT_MARGIN_SIDE);
    TranslateAnimation anim = new TranslateAnimation(0, horizontalDistance, 0, 0);
    anim.setDuration(ANIMATION_DURATION);
    anim.setAnimationListener(new Animation.AnimationListener() {
        @Override
        public void onAnimationStart(Animation animation) {}

        @Override
        public void onAnimationEnd(Animation animation) {
            ConstraintSet set = new ConstraintSet();
            ConstraintLayout l = findViewById(R.id.custom_edit_text_constraint_layout);
            set.clone(l);
            set.clear(R.id.custom_edit_text_hint, ConstraintSet.RIGHT);
            set.connect(R.id.custom_edit_text_hint, ConstraintSet.LEFT, R.id.custom_edit_text_constraint_layout, ConstraintSet.LEFT, dpToPx(HINT_MARGIN_SIDE));
            set.applyTo(l);
        }

        @Override
        public void onAnimationRepeat(Animation animation) {}
    });
    hint.startAnimation(anim);
}

This works great, but only when I don't resize the TextSize of the TextView. When I resize the TextSize (as shown in the code), hint.getLeft() and hint.getRight() return the values, which the TextView would have with the old TextSize, and this results in that the TextView moves either too far or not far enought. But this doesn't make sense to me because I resize the TextSize BEFORE I start the animation and the TextView's width is set to wrap_content. Does anyone have an idea why this doesn't work and how I can fix it?

EDIT:

To further explain and simplify what exactly the problem is, I have an example:

textView.setTextSize(12);
int width1 = hint.getWidth();
textView.setTextSize(18);
int width2 = hint.getWidth();

As the TextView's width is set to wrap_content, the width should change when I change the textSize (at least I thought so). But width1 and width2 are the same. How can I fix that?

EDIT2:

I solved the problem with this answer by Eric.

Apri
  • 1,241
  • 1
  • 8
  • 33

1 Answers1

0

Add right and end constraint of the textview as follows.If you want it to be in middle then set horizontal_bias = 0.5 or if you want it left then 0.0 and lastly in right 1.0

<TextView
            android:id="@+id/custom_edit_text_hint"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            app:layout_constraintLeft_toLeftOf="parent"
            app:layout_constraintTop_toTopOf="parent"
            app:layout_constraintBottom_toBottomOf="parent"
            android:layout_marginLeft="@dimen/custom_edittext_def_hint_margin"
            android:layout_marginStart="@dimen/custom_edittext_def_hint_margin"
            android:layout_constraintRight_toRightOf = "parent"
            android:layout_constraintEnd_toEndOf = "parent"
            app:layout_constraintHorizontal_bias="0.0"
          />

Hope this will work.Try it

Rezaul Karim
  • 830
  • 8
  • 15
  • Thank you for your answer! But the fixed position after the animation is right. What's wrong is the position where the `TextView` moves during the animation. It moves too far / not far enought, but when I set the new constraints, it is at the right position. So, what's wrong is the `horizontalDistance` – Apri Sep 17 '19 at 10:51
  • you can move it by changing the horizontal_bias from 0.0 to 1.0 – Rezaul Karim Sep 17 '19 at 10:54
  • I need to move it programmatically with an animation. – Apri Sep 17 '19 at 11:12
  • okay.. give me some time i will send you demo.. how to animate it programmatically. it wil be quite easy – Rezaul Karim Sep 17 '19 at 11:14
  • I edited an example to better simplify my problem. Maybe you can help me now. – Apri Sep 18 '19 at 07:34