Skip to content

Instantly share code, notes, and snippets.

@drstranges
Last active April 21, 2020 07:10
Show Gist options
  • Save drstranges/1a86965f582f610244d6 to your computer and use it in GitHub Desktop.
Save drstranges/1a86965f582f610244d6 to your computer and use it in GitHub Desktop.
TextInputLayout temporary workaround for helper text showing
<?xml version="1.0" encoding="utf-8"?>
<resources>
<declare-styleable name="CustomTextInputLayout">
<attr name="helperText" format="string"/>
<attr name="helperTextColor" format="color|reference"/>
</declare-styleable>
<style name="HelperTextAppearance" parent="TextAppearance.Design.Error">
<item name="android:textColor">@color/secondary_text</item>
</style>
</resources>
package com.example.d_rom.supportdesigndemo.widget;
import android.content.Context;
import android.content.res.ColorStateList;
import android.content.res.TypedArray;
import android.support.design.widget.TextInputLayout;
import android.support.v4.view.ViewCompat;
import android.support.v4.view.ViewPropertyAnimatorListenerAdapter;
import android.support.v4.view.animation.FastOutSlowInInterpolator;
import android.text.TextUtils;
import android.util.AttributeSet;
import android.view.View;
import android.view.ViewGroup;
import android.view.animation.Interpolator;
import android.widget.EditText;
import android.widget.TextView;
import com.example.d_rom.supportdesigndemo.R;
/**
* TextInputLayout temporary workaround for helper text showing
*/
public class CustomTextInputLayout extends TextInputLayout {
static final Interpolator FAST_OUT_SLOW_IN_INTERPOLATOR = new FastOutSlowInInterpolator();
private CharSequence mHelperText;
private ColorStateList mHelperTextColor;
private boolean mHelperTextEnabled = false;
private boolean mErrorEnabled = false;
private TextView mHelperView;
private int mHelperTextAppearance = R.style.HelperTextAppearance;
public CustomTextInputLayout(Context _context) {
super(_context);
}
public CustomTextInputLayout(Context _context, AttributeSet _attrs) {
super(_context, _attrs);
final TypedArray a = getContext().obtainStyledAttributes(
_attrs,
R.styleable.CustomTextInputLayout,0,0);
try {
mHelperTextColor = a.getColorStateList(R.styleable.CustomTextInputLayout_helperTextColor);
mHelperText = a.getText(R.styleable.CustomTextInputLayout_helperText);
} finally {
a.recycle();
}
}
@Override
public void addView(View child, int index, ViewGroup.LayoutParams params) {
super.addView(child, index, params);
if (child instanceof EditText) {
if (!TextUtils.isEmpty(mHelperText)) {
setHelperText(mHelperText);
}
}
}
public int getHelperTextAppearance() {
return mHelperTextAppearance;
}
public void setHelperTextAppearance(int _helperTextAppearanceResId) {
mHelperTextAppearance = _helperTextAppearanceResId;
}
public void setHelperTextColor(ColorStateList _helperTextColor) {
mHelperTextColor = _helperTextColor;
}
public void setHelperTextEnabled(boolean _enabled) {
if (mHelperTextEnabled == _enabled) return;
if (_enabled && mErrorEnabled) {
setErrorEnabled(false);
}
if (this.mHelperTextEnabled != _enabled) {
if (_enabled) {
this.mHelperView = new TextView(this.getContext());
this.mHelperView.setTextAppearance(this.getContext(), this.mHelperTextAppearance);
if (mHelperTextColor != null){
this.mHelperView.setTextColor(mHelperTextColor);
}
this.mHelperView.setVisibility(INVISIBLE);
this.addView(this.mHelperView);
if (this.mHelperView != null) {
ViewCompat.setPaddingRelative(
this.mHelperView,
ViewCompat.getPaddingStart(getEditText()),
0, ViewCompat.getPaddingEnd(getEditText()),
getEditText().getPaddingBottom());
}
} else {
this.removeView(this.mHelperView);
this.mHelperView = null;
}
this.mHelperTextEnabled = _enabled;
}
}
public void setHelperText(CharSequence _helperText) {
mHelperText = _helperText;
if (!this.mHelperTextEnabled) {
if (TextUtils.isEmpty(mHelperText)) {
return;
}
this.setHelperTextEnabled(true);
}
if (!TextUtils.isEmpty(mHelperText)) {
this.mHelperView.setText(mHelperText);
this.mHelperView.setVisibility(VISIBLE);
ViewCompat.setAlpha(this.mHelperView, 0.0F);
ViewCompat.animate(this.mHelperView)
.alpha(1.0F).setDuration(200L)
.setInterpolator(FAST_OUT_SLOW_IN_INTERPOLATOR)
.setListener(null).start();
} else if (this.mHelperView.getVisibility() == VISIBLE) {
ViewCompat.animate(this.mHelperView)
.alpha(0.0F).setDuration(200L)
.setInterpolator(FAST_OUT_SLOW_IN_INTERPOLATOR)
.setListener(new ViewPropertyAnimatorListenerAdapter() {
public void onAnimationEnd(View view) {
mHelperView.setText(null);
mHelperView.setVisibility(INVISIBLE);
}
}).start();
}
this.sendAccessibilityEvent(2048);
}
@Override
public void setErrorEnabled(boolean _enabled) {
if (mErrorEnabled == _enabled) return;
mErrorEnabled = _enabled;
if (_enabled && mHelperTextEnabled) {
setHelperTextEnabled(false);
}
super.setErrorEnabled(_enabled);
if (!(_enabled || TextUtils.isEmpty(mHelperText))) {
setHelperText(mHelperText);
}
}
}
<com.example.d_rom.supportdesigndemo.widget.CustomTextInputLayout
android:id="@+id/tilCustom"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:helperText="@string/input_helper_text"
app:helperTextColor="@color/secondary_text">
<EditText
android:id="@+id/etCustom"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="Custom InputTextLayout with Helper Text"/>
</com.example.d_rom.supportdesigndemo.widget.CustomTextInputLayout>
@KirillJJ
Copy link

The code above has some troubles with TextInputLayout's counterin method setHelperTextEnabled.
I fixed this problem in code below.

` public void setHelperTextEnabled(boolean _enabled) {
if (mHelperTextEnabled == _enabled) return;
if (_enabled && mErrorEnabled) {
setErrorEnabled(false);
}
if (this.mHelperTextEnabled != _enabled) {
if (_enabled) {
this.mHelperView = new TextView(this.getContext());
this.mHelperView.setTextAppearance(this.getContext(), this.mHelperTextAppearance);
if (mHelperTextColor != null){
this.mHelperView.setTextColor(mHelperTextColor);
}
this.mHelperView.setVisibility(INVISIBLE);
View view = getChildAt(1);
if (view != null && view instanceof LinearLayout){
((ViewGroup) view).addView(mHelperView, 0);
} else {
this.addView(this.mHelperView);
if (this.mHelperView != null) {
ViewCompat.setPaddingRelative(
this.mHelperView,
ViewCompat.getPaddingStart(getEditText()),
0, ViewCompat.getPaddingEnd(getEditText()),
getEditText().getPaddingBottom());
}
}
} else {
this.removeView(this.mHelperView);
this.mHelperView = null;
}

        this.mHelperTextEnabled = _enabled;
    }
}

`

@dimitrihartt
Copy link

dimitrihartt commented Dec 29, 2018

There is still an error in this code which gives me this error:
Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'int android.view.View.getPaddingStart()' on a null object reference
at android.support.v4.view.ViewCompat.getPaddingStart(ViewCompat.java:1527)
at com.sample.app.widget.HelperTextInputLayout.setHelperTextEnabled(CustomTextInputLayout.java:97)
at com.sample.app.widget.HelperTextInputLayout.setHelperText(CustomTextInputLayout.java:116)
at android.support.design.widget.TextInputLayout.(TextInputLayout.java:361)
at android.support.design.widget.TextInputLayout.(TextInputLayout.java:247)
at com.sample.app.widget.CustomTextInputLayout.(CustomTextInputLayout.java:41)

exactly on:
97 ViewCompat.getPaddingStart(getEditText()), -> (Argument getEditText() might be null more...) InteliJ said.
116 this.setHelperTextEnabled(true);
41 super(_context, _attrs);

Please help me.

@dimitrihartt
Copy link

Please! Can anyone help?

@drstranges
Copy link
Author

@dimitrileite Please, check that CustomTextInputLayout explicitly wraps EditText in layout like that: https://gist.github.com/drstranges/1a86965f582f610244d6#file-usage-xml

If the problem persists, why not migrate to the new version of TextInputLayout, where the "helper text" has already been implemented.

@dimitrihartt
Copy link

@dimitrileite Please, check that CustomTextInputLayout explicitly wraps EditText in layout like that: https://gist.github.com/drstranges/1a86965f582f610244d6#file-usage-xml

If the problem persists, why not migrate to the new version of TextInputLayout, where the "helper text" has already been implemented.

You are right my friend! Thank you!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment