2016-07-12 14 views
9
konzentriert

Was ich tun möchte:TextInputLayout: Unterschiedliche Farbe für Hinweis Etikett, wenn nicht

Wenn ein EditText in einem TextInputLayout ich will eingebettet mit ...

  1. Stellen Sie die Farbe des Beschriftung auf GRÜN, wenn es defokussiert und über dem EditText schwebt, da der Benutzer bereits einen Wert eingegeben hat
  2. Setzen Sie die Farbe der Beschriftung auf ROT, wenn sie defokussiert ist und sich im EditText befindet, da der Benutzer noch nicht eingegeben hat ein Wert
  3. Ich möchte nicht die Hinweistextfarbe aller meiner EditTexte in ROT ändern, sondern nur wenn sie in ein TextInputLayout eingebunden sind (ich brauche keinen allgemeinen Ansatz - einen spezifischen Ansatz wie das Festlegen eines Themas/Styles für jeden TextInputLayout im Layout XML wäre in Ordnung)
  4. Preserve (dh nicht ändern) die Akzentfarbe (GELB), die verwendet wird, um das Floating-Label zu färben, wenn der Benutzer das Feld fokussiert hat.

Was ich versucht habe:

Einstellen der unten als Thema/Stil auf dem TextInputLayout 1. nicht erfüllt, aber nicht 2.

<style name="FloatingLabel" parent="Widget.Design.TextInputLayout"> 
    <item name="android:textColorHint">@color/red</item> 
</style> 

Einstellung eine bestimmte Farbe auf meinem eingebetteten EditText, der den Hinweistext in eine andere Farbe ändert:

android:textColorHint="@color/text_placeholder_gray" 

verursacht tatsächlich eine Überlappung von Hinweistexten, wenn das Etikett von seiner schwebenden Position zurück in den Editiertext als Hinweis bewegt wird (d. h. kein Text).

dieser Einstellung:

<style name="TextAppearence.App.TextInputLayout" parent="@android:style/TextAppearance"> 
<item name="android:textColor">@color/main_color</item> 

auf dem TextInputLayout:

<android.support.design.widget.TextInputLayout 
    ... 
    app:hintTextAppearance="@style/TextAppearence.App.TextInputLayout" > 

ändert die Farbe der Labels Hinweis aber es funktioniert auch so für den fokussierten Zustand - was bedeutet, 4 nicht erfüllt ist.

Und da ein Bild sagt mehr als Worte tousand (alle Felder sind in nicht-fokussierten Zustand):

enter image description here

Wie ein Setup zu erreichen, die 1-4 Kriterien erfüllt?

Antwort

3

Ich hatte ein ähnliches Problem: Ich musste ein Texteingabelayout implementieren, in dem das Etikett verschiedene Farben für leer (wenn kein Text im Bearbeitungstext eingegeben wird), "gefüllt" und fokussierten Zustand. Mein Hauptproblem bestand darin, zwischen dem leeren und dem gefüllten Zustand zu unterscheiden, da das Setzen einer anderen Farbe für den fokussierten Zustand bereits leicht mit Selektoren möglich war. Am Ende entschied ich mich, einen benutzerdefinierten "leeren Text" -Zustand zu definieren und mein benutzerdefiniertes Texteingabe-Layout zu implementieren (welches das normale Texteingabe-Layout erweitert). Hier

ist ein Code:

In res/Werte/attrs.xml:

<?xml version="1.0" encoding="utf-8"?> 
<resources> 

... 

    <!-- Custom state for the text input layout to determine whether the label is shown above some text or not --> 
    <declare-styleable name="EmptyTextState"> 
     <attr name="state_empty_text" format="boolean"/> 
    </declare-styleable> 

</resources> 

Das benutzerdefinierte Texteingabelayout:

public class EmptyStateTextInputLayout extends TextInputLayout { 
    private boolean emptyText = true; 
    private static final int[] EMPTY_TEXT_STATE = new int[]{R.attr.state_empty_text}; 

    public EmptyStateTextInputLayout(Context context) { 
     super(context); 
    } 

    public EmptyStateTextInputLayout(Context context, AttributeSet attrs) { 
     super(context, attrs); 
    } 

    public EmptyStateTextInputLayout(Context context, AttributeSet attrs, int defStyleAttr) { 
     super(context, attrs, defStyleAttr); 
    } 

    @Override 
    protected int[] onCreateDrawableState(int extraSpace) { 
     int[] state = super.onCreateDrawableState(extraSpace + 1); 
     if (emptyText) { 
      mergeDrawableStates(state, EMPTY_TEXT_STATE); 
     } 
     return state; 
    } 

    public void setEmptyTextState(boolean emptyTextState) { 
     this.emptyText = emptyTextState; 
     refreshDrawableState(); 
    } 

    @Override 
    public void addView(View child, int index, ViewGroup.LayoutParams params) { 
     if (child instanceof EditText) { 
      EditText editText = (EditText) child; 
      if (!TextUtils.isEmpty(editText.getText())) { 
       setEmptyTextState(false); 
      } 
      editText.addTextChangedListener(new TextWatcher() { 
       @Override 
       public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) { 

       } 

       @Override 
       public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) { 

       } 

       @Override 
       public void afterTextChanged(Editable editable) { 
        if (!TextUtils.isEmpty(editable)) { 
         setEmptyTextState(false); 
        } else { 
         setEmptyTextState(true); 
        } 
       } 
      }); 
     } 
     super.addView(child, index, params); 
    } 
} 

XML-Selektor die Farbe des Etiketts in verschiedenen Zuständen (res/Farbe/input_field_floating_label.xml) einzustellen:

<?xml version="1.0" encoding="utf-8"?> 
<selector xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto"> 
    <item android:color="@color/focused_text_color" android:state_focused="true" /> 
    <item android:color="@color/placeholder_color" app:state_empty_text="true"/> 
    <item android:color="@color/primary_text_color"/> <!-- default color --> 
</selector> 

Stil für das Eingabetextlayout (in res/values ​​/ styles.xml):

<style name="EditTextLayout"> 
    ... 
    <item name="android:textColorHint">@color/input_field_floating_label</item> 
</style> 

Thema und Stil für das Bearbeiten von Text (noch in res/Werte/styles.xml):

<style name="EditTextTheme"> 
    ... 
    <item name="android:textColorHint">@color/input_field_floating_label</item> 
</style> 

<style name="EditText"> 
    <item name="android:theme">@style/EditTextTheme</item> 
    ... 
</style> 

Verbrauch:

<com.package.path.widget.EmptyStateTextInputLayout 
      style="@style/DarkEditTextLayout" 
      android:layout_height="wrap_content" 
      android:layout_width="match_parent" 
      ... 
      > 

      <EditText 
       style="@style/EditText" 
       android:layout_width="match_parent" 
       android:layout_height="wrap_content" /> 
</com.package.path.widget.EmptyStateTextInputLayout> 

ich diesen Blog-Post empfehlen eine Vorstellung von der Arbeit mit Gewohnheit zu bekommen Zustände: http://code.neenbedankt.com/example-of-custom-states-in-android-components/