Java tutorial
/* * Copyright (C) 2016 Tobias Brunner * HSR Hochschule fuer Technik Rapperswil * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the * Free Software Foundation; either version 2 of the License, or (at your * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * for more details. */ package org.strongswan.android.ui.view; import android.content.Context; import android.content.res.TypedArray; import android.support.annotation.Nullable; import android.support.design.widget.TextInputLayout; import android.support.v4.view.ViewCompat; import android.support.v4.view.ViewPropertyAnimatorListenerAdapter; import android.text.Editable; import android.text.TextWatcher; import android.util.AttributeSet; import android.util.TypedValue; import android.view.View; import android.view.ViewGroup; import android.widget.EditText; import android.widget.LinearLayout; import android.widget.TextView; import org.strongswan.android.R; /** * Layout that extends {@link android.support.design.widget.TextInputLayout} with a helper text * displayed below the text field when it receives the focus. Also, any error message shown with * {@link #setError(CharSequence)} is hidden when the text field is changed (this mirrors the * behavior of {@link android.widget.EditText}). */ public class TextInputLayoutHelper extends TextInputLayout { private LinearLayout mHelperContainer; private TextView mHelperText; public TextInputLayoutHelper(Context context) { this(context, null); } public TextInputLayoutHelper(Context context, AttributeSet attrs) { this(context, attrs, 0); } public TextInputLayoutHelper(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs); TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.TextInputLayoutHelper); String helper = a.getString(R.styleable.TextInputLayoutHelper_helper_text); a.recycle(); if (helper != null) { mHelperContainer = new LinearLayout(context); mHelperContainer.setOrientation(LinearLayout.HORIZONTAL); mHelperContainer.setVisibility(View.INVISIBLE); addView(mHelperContainer, LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT); mHelperText = new TextView(context); mHelperText.setText(helper); mHelperText.setTextSize(TypedValue.COMPLEX_UNIT_SP, 12); a = context.obtainStyledAttributes(attrs, new int[] { android.R.attr.textColorSecondary }); mHelperText.setTextColor(a.getColor(0, mHelperText.getCurrentTextColor())); a.recycle(); mHelperContainer.addView(mHelperText, LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT); } } @Override public void addView(View child, int index, ViewGroup.LayoutParams params) { super.addView(child, index, params); if (child instanceof EditText) { EditText text = (EditText) child; text.addTextChangedListener(new TextWatcher() { @Override public void beforeTextChanged(CharSequence s, int start, int count, int after) { } @Override public void onTextChanged(CharSequence s, int start, int before, int count) { } @Override public void afterTextChanged(Editable s) { if (getError() != null) { setError(null); } } }); if (mHelperContainer != null) { text.setOnFocusChangeListener(new OnFocusChangeListener() { @Override public void onFocusChange(View v, boolean hasFocus) { showHelper(hasFocus); } }); ViewCompat.setPaddingRelative(mHelperContainer, ViewCompat.getPaddingStart(text), 0, ViewCompat.getPaddingEnd(text), text.getPaddingBottom()); } } } @Override public void setError(@Nullable CharSequence error) { super.setError(error); if (mHelperContainer != null) { if (error == null) { /* this frees up space used by the now invisible error message */ setErrorEnabled(false); } else { /* re-add the helper as the error message should be displayed directly under the textbox */ removeView(mHelperContainer); addView(mHelperContainer, LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT); } } } /** * Set the helper text to be displayed below the text field. * * @attr ref R.styleable#TextInputLayoutHelper_helper_text */ public void setHelperText(CharSequence text) { mHelperText.setText(text); } private void showHelper(boolean show) { if (show == (mHelperContainer.getVisibility() == View.VISIBLE)) { return; } if (show) { ViewCompat.animate(mHelperContainer).alpha(1f).setDuration(200) .setListener(new ViewPropertyAnimatorListenerAdapter() { @Override public void onAnimationStart(View view) { view.setVisibility(View.VISIBLE); } }).start(); } else { ViewCompat.animate(mHelperContainer).alpha(0f).setDuration(200) .setListener(new ViewPropertyAnimatorListenerAdapter() { @Override public void onAnimationEnd(View view) { view.setVisibility(View.INVISIBLE); } }).start(); } } }