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.