Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
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>
@drstranges

This comment has been minimized.

Copy link
Owner Author

@drstranges drstranges commented Mar 8, 2017

Copyright 2015 Roman Donchenko

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

@KirillJJ

This comment has been minimized.

Copy link

@KirillJJ KirillJJ commented Jul 31, 2017

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

`

@dimitrileite

This comment has been minimized.

Copy link

@dimitrileite dimitrileite 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.

@dimitrileite

This comment has been minimized.

Copy link

@dimitrileite dimitrileite commented Sep 3, 2019

Please! Can anyone help?

@drstranges

This comment has been minimized.

Copy link
Owner Author

@drstranges drstranges commented Sep 4, 2019

@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.

@dimitrileite

This comment has been minimized.

Copy link

@dimitrileite dimitrileite commented Oct 27, 2019

@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