From: Tobias Brunner Date: Fri, 29 Apr 2016 16:15:29 +0000 (+0200) Subject: android: Add TextInputLayout child class that displays a helper text below the text... X-Git-Tag: 5.4.1dr2~16^2~8 X-Git-Url: https://git.strongswan.org/?p=strongswan.git;a=commitdiff_plain;h=79ba4b285f4aa836346a7afe2bdb206e05d72304;hp=5ffd79b39b52df041b25e6a27706f8d0f8ff7c4a;ds=sidebyside android: Add TextInputLayout child class that displays a helper text below the text field Also hides the error message if the text is changed. --- diff --git a/src/frontends/android/app/src/main/java/org/strongswan/android/ui/widget/TextInputLayoutHelper.java b/src/frontends/android/app/src/main/java/org/strongswan/android/ui/widget/TextInputLayoutHelper.java new file mode 100644 index 0000000..45b0ae5 --- /dev/null +++ b/src/frontends/android/app/src/main/java/org/strongswan/android/ui/widget/TextInputLayoutHelper.java @@ -0,0 +1,180 @@ +/* + * 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 . + * + * 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.widget; + +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(); + } + } +} diff --git a/src/frontends/android/app/src/main/res/values/attrs.xml b/src/frontends/android/app/src/main/res/values/attrs.xml index 6c3480b..592555c 100644 --- a/src/frontends/android/app/src/main/res/values/attrs.xml +++ b/src/frontends/android/app/src/main/res/values/attrs.xml @@ -1,7 +1,7 @@