Change text colors to reflect their state

The editor's text color suffered from two conflicting
problems
1) It didn't all pass GAR
2) The difference between hint text and regular text
 is too subtle to differentiate at a glance

Changes
1) Once a LabeledEditorView is non-empty, the text color of
 the spinner should no longer be the hint text color
2) Once an editor field is focused, all fields in the same
 EditKindSection get a slightly darker color. Since the various
 name editors, don't actually belong to a EditKindSection
 extra work needed to be done for them.
3) Drop down lists use non hint colors

Read only editor continues to use the darker hint color.
There is no need to strongly distinquish hint colors from
non hint colors in the read only editor.

Bug: 18004959
Change-Id: Ia6b16ab882b2fcb9113c2ac880e741f62115a1f9
diff --git a/src/com/android/contacts/editor/ContactEditorFragment.java b/src/com/android/contacts/editor/ContactEditorFragment.java
index 4ff6b9e..2ca44c2 100644
--- a/src/com/android/contacts/editor/ContactEditorFragment.java
+++ b/src/com/android/contacts/editor/ContactEditorFragment.java
@@ -892,6 +892,8 @@
                         }
                         if (request == EditorListener.FIELD_CHANGED && !isEditingUserProfile()) {
                             acquireAggregationSuggestions(activity, rawContactEditor);
+                        } else if (request == EditorListener.EDITOR_FOCUS_CHANGED) {
+                            adjustNameFieldsHintDarkness(rawContactEditor);
                         }
                     }
 
@@ -915,9 +917,15 @@
                 phoneticNameEditor.setEditorListener(listener);
                 rawContactEditor.setAutoAddToDefaultGroup(mAutoAddToDefaultGroup);
 
+                final TextFieldsEditorView nickNameEditor =
+                        rawContactEditor.getNickNameEditor();
+                nickNameEditor.setEditorListener(listener);
+
                 if (rawContactId == mAggregationSuggestionsRawContactId) {
                     acquireAggregationSuggestions(activity, rawContactEditor);
                 }
+
+                adjustNameFieldsHintDarkness(rawContactEditor);
             }
         }
 
@@ -937,6 +945,23 @@
     }
 
     /**
+     * Adjust how dark the hint text should be on all the names' text fields.
+     *
+     * @param rawContactEditor editor to update
+     */
+    private void adjustNameFieldsHintDarkness(RawContactEditorView rawContactEditor) {
+        // Check whether fields contain focus by calling findFocus() instead of hasFocus().
+        // The hasFocus() value is not necessarily up to date.
+        final boolean nameFieldsAreNotFocused
+                = rawContactEditor.getNameEditor().findFocus() == null
+                && rawContactEditor.getPhoneticNameEditor().findFocus() == null
+                && rawContactEditor.getNickNameEditor().findFocus() == null;
+        rawContactEditor.getNameEditor().setHintColorDark(!nameFieldsAreNotFocused);
+        rawContactEditor.getPhoneticNameEditor().setHintColorDark(!nameFieldsAreNotFocused);
+        rawContactEditor.getNickNameEditor().setHintColorDark(!nameFieldsAreNotFocused);
+    }
+
+    /**
      * Update the values in {@link #mExpandedEditors}.
      */
     private void updatedExpandedEditorsMap() {
diff --git a/src/com/android/contacts/editor/Editor.java b/src/com/android/contacts/editor/Editor.java
index bda5c6e..73b950a 100644
--- a/src/com/android/contacts/editor/Editor.java
+++ b/src/com/android/contacts/editor/Editor.java
@@ -49,6 +49,9 @@
         // The editor has switched between different representations of the same
         // data, e.g. from full name to structured name
         public static final int EDITOR_FORM_CHANGED = 5;
+
+        // Focus has changed inside the editor.
+        public static final int EDITOR_FOCUS_CHANGED = 6;
     }
 
     /**
diff --git a/src/com/android/contacts/editor/EventFieldEditorView.java b/src/com/android/contacts/editor/EventFieldEditorView.java
index 34a10cd..246ee9c 100644
--- a/src/com/android/contacts/editor/EventFieldEditorView.java
+++ b/src/com/android/contacts/editor/EventFieldEditorView.java
@@ -52,7 +52,7 @@
      */
     private String mNoDateString;
     private int mPrimaryTextColor;
-    private int mSecondaryTextColor;
+    private int mHintTextColor;
 
     private Button mDateView;
 
@@ -75,7 +75,7 @@
 
         Resources resources = mContext.getResources();
         mPrimaryTextColor = resources.getColor(R.color.primary_text_color);
-        mSecondaryTextColor = resources.getColor(R.color.secondary_text_color);
+        mHintTextColor = resources.getColor(R.color.editor_disabled_text_color);
         mNoDateString = mContext.getString(R.string.event_edit_field_hint_text);
 
         mDateView = (Button) findViewById(R.id.date_view);
@@ -123,7 +123,7 @@
                 false /*Use the short DateFormat to ensure that it fits inside the EditText*/);
         if (TextUtils.isEmpty(data)) {
             mDateView.setText(mNoDateString);
-            mDateView.setTextColor(mSecondaryTextColor);
+            mDateView.setTextColor(mHintTextColor);
             setDeleteButtonVisible(false);
         } else {
             mDateView.setText(data);
@@ -256,7 +256,7 @@
     public void clearAllFields() {
         // Update UI
         mDateView.setText(mNoDateString);
-        mDateView.setTextColor(mSecondaryTextColor);
+        mDateView.setTextColor(mHintTextColor);
 
         // Update state
         final String column = getKind().fieldList.get(0).column;
diff --git a/src/com/android/contacts/editor/GroupMembershipView.java b/src/com/android/contacts/editor/GroupMembershipView.java
index 5752a47..e0d78b5 100644
--- a/src/com/android/contacts/editor/GroupMembershipView.java
+++ b/src/com/android/contacts/editor/GroupMembershipView.java
@@ -116,6 +116,9 @@
         @Override
         public View getView(int position, View convertView, ViewGroup parent) {
             final View itemView = super.getView(position, convertView, parent);
+            if (itemView == null) {
+                return null;
+            }
 
             // Hide the checkable drawable.  This assumes that the item views
             // are CheckedTextView objects
@@ -123,6 +126,7 @@
             if (!getItemIsCheckable(position)) {
                 checkedTextView.setCheckMarkDrawable(null);
             }
+            checkedTextView.setTextColor(mPrimaryTextColor);
 
             return checkedTextView;
         }
@@ -145,7 +149,7 @@
 
     private String mNoGroupString;
     private int mPrimaryTextColor;
-    private int mSecondaryTextColor;
+    private int mHintTextColor;
 
     public GroupMembershipView(Context context) {
         super(context);
@@ -160,7 +164,7 @@
         super.onFinishInflate();
         Resources resources = mContext.getResources();
         mPrimaryTextColor = resources.getColor(R.color.primary_text_color);
-        mSecondaryTextColor = resources.getColor(R.color.secondary_text_color);
+        mHintTextColor = resources.getColor(R.color.editor_disabled_text_color);
         mNoGroupString = mContext.getString(R.string.group_edit_field_hint_text);
     }
 
@@ -266,7 +270,7 @@
         mGroupList.setEnabled(isEnabled());
         if (sb.length() == 0) {
             mGroupList.setText(mNoGroupString);
-            mGroupList.setTextColor(mSecondaryTextColor);
+            mGroupList.setTextColor(mHintTextColor);
         } else {
             mGroupList.setText(sb);
             mGroupList.setTextColor(mPrimaryTextColor);
diff --git a/src/com/android/contacts/editor/LabeledEditorView.java b/src/com/android/contacts/editor/LabeledEditorView.java
index c280062..caf02b1 100644
--- a/src/com/android/contacts/editor/LabeledEditorView.java
+++ b/src/com/android/contacts/editor/LabeledEditorView.java
@@ -239,6 +239,10 @@
         mListener = listener;
     }
 
+    protected EditorListener getEditorListener(){
+        return mListener;
+    }
+
     @Override
     public void setDeletable(boolean deletable) {
         mIsDeletable = deletable;
@@ -276,7 +280,7 @@
      * Build the current label state based on selected {@link EditType} and
      * possible custom label string.
      */
-    private void rebuildLabel() {
+    public void rebuildLabel() {
         mEditTypeAdapter = new EditTypeAdapter(mContext);
         mLabel.setAdapter(mEditTypeAdapter);
         if (mEditTypeAdapter.hasCustomSelection()) {
@@ -297,6 +301,8 @@
 
         // Notify listener if applicable
         notifyEditorListener();
+
+        rebuildLabel();
     }
 
     protected void saveValue(String column, String value) {
@@ -527,12 +533,18 @@
     private class EditTypeAdapter extends ArrayAdapter<EditType> {
         private final LayoutInflater mInflater;
         private boolean mHasCustomSelection;
-        private int mTextColor;
+        private int mTextColorHintUnfocused;
+        private int mTextColorDark;
+        private int mTextColorSecondary;
 
         public EditTypeAdapter(Context context) {
             super(context, 0);
             mInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
-            mTextColor = context.getResources().getColor(R.color.secondary_text_color);
+            mTextColorHintUnfocused = context.getResources().getColor(
+                    R.color.editor_disabled_text_color);
+            mTextColorSecondary = context.getResources().getColor(R.color.secondary_text_color);
+            mTextColorDark = context.getResources().getColor(R.color.primary_text_color);
+
 
             if (mType != null && mType.customColumn != null) {
 
@@ -553,11 +565,21 @@
 
         @Override
         public View getView(int position, View convertView, ViewGroup parent) {
-            final View view = createViewFromResource(
+            final TextView view = createViewFromResource(
                     position, convertView, parent, R.layout.edit_simple_spinner_item);
             // We don't want any background on this view. The background would obscure
             // the spinner's background.
             view.setBackground(null);
+            // The text color should be a very light hint color when unfocused and empty. When
+            // focused and empty, use a less light hint color. When non-empty, use a dark non-hint
+            // color.
+            if (!LabeledEditorView.this.isEmpty()) {
+                view.setTextColor(mTextColorDark);
+            } else if (LabeledEditorView.this.hasFocus()) {
+                view.setTextColor(mTextColorSecondary);
+            } else {
+                view.setTextColor(mTextColorHintUnfocused);
+            }
             return view;
         }
 
@@ -567,7 +589,7 @@
                     position, convertView, parent, android.R.layout.simple_spinner_dropdown_item);
         }
 
-        private View createViewFromResource(int position, View convertView, ViewGroup parent,
+        private TextView createViewFromResource(int position, View convertView, ViewGroup parent,
                 int resource) {
             TextView textView;
 
@@ -575,7 +597,7 @@
                 textView = (TextView) mInflater.inflate(resource, parent, false);
                 textView.setTextSize(TypedValue.COMPLEX_UNIT_PX, getResources().getDimension(
                         R.dimen.editor_form_text_size));
-                textView.setTextColor(mTextColor);
+                textView.setTextColor(mTextColorDark);
             } else {
                 textView = (TextView) convertView;
             }
diff --git a/src/com/android/contacts/editor/RawContactEditorView.java b/src/com/android/contacts/editor/RawContactEditorView.java
index a3d2f09..e56571d 100644
--- a/src/com/android/contacts/editor/RawContactEditorView.java
+++ b/src/com/android/contacts/editor/RawContactEditorView.java
@@ -64,7 +64,8 @@
 
     private StructuredNameEditorView mName;
     private PhoneticNameEditorView mPhoneticName;
-    private KindSectionView mNickNameSectionView;
+    private TextFieldsEditorView mNickName;
+
     private GroupMembershipView mGroupMembershipView;
 
     private ViewGroup mFields;
@@ -132,7 +133,7 @@
         mPhoneticName = (PhoneticNameEditorView)findViewById(R.id.edit_phonetic_name);
         mPhoneticName.setDeletable(false);
 
-        mNickNameSectionView = (KindSectionView)findViewById(R.id.edit_nick_name);
+        mNickName = (TextFieldsEditorView)findViewById(R.id.edit_nick_name);
 
         mFields = (ViewGroup)findViewById(R.id.sect_fields);
 
@@ -264,11 +265,10 @@
                 mPhoneticName.setValues(
                         type.getKindForMimetype(DataKind.PSEUDO_MIME_TYPE_PHONETIC_NAME),
                         primary, state, false, vig);
-                // Special case for nick name, so it gets inserted in the header section. It
-                // should look like it belongs to the same KindSectionView as the other name fields.
-                mNickNameSectionView.setEnabled(isEnabled());
-                mNickNameSectionView.setState(type.getKindForMimetype(Nickname.CONTENT_ITEM_TYPE),
-                        state, false, vig);
+                mNickName.setValues(
+                        type.getKindForMimetype(Nickname.CONTENT_ITEM_TYPE),
+                        primary, state, false, vig);
+                mNickName.setDeletable(false);
             } else if (Photo.CONTENT_ITEM_TYPE.equals(mimeType)) {
                 // Handle special case editor for photos
                 final ValuesDelta primary = state.getPrimaryEntry(mimeType);
@@ -378,6 +378,10 @@
         return mPhoneticName;
     }
 
+    public TextFieldsEditorView getNickNameEditor() {
+        return mNickName;
+    }
+
     @Override
     public long getRawContactId() {
         return mRawContactId;
diff --git a/src/com/android/contacts/editor/TextFieldsEditorView.java b/src/com/android/contacts/editor/TextFieldsEditorView.java
index 03e49fa..bb5210a 100644
--- a/src/com/android/contacts/editor/TextFieldsEditorView.java
+++ b/src/com/android/contacts/editor/TextFieldsEditorView.java
@@ -60,6 +60,7 @@
     private int mMinFieldHeight;
     private int mPreviousViewHeight;
     private int mHintTextColor;
+    private int mHintTextColorUnfocused;
 
     public TextFieldsEditorView(Context context) {
         super(context);
@@ -85,6 +86,7 @@
                 R.dimen.editor_min_line_item_height);
         mFields = (ViewGroup) findViewById(R.id.editors);
         mHintTextColor = getResources().getColor(R.color.secondary_text_color);
+        mHintTextColorUnfocused = getResources().getColor(R.color.editor_disabled_text_color);
         mExpansionView = (ImageView) findViewById(R.id.expansion_view);
         mExpansionViewContainer = findViewById(R.id.expansion_view_container);
         if (mExpansionViewContainer != null) {
@@ -146,6 +148,36 @@
         }
     }
 
+    private OnFocusChangeListener mTextFocusChangeListener = new OnFocusChangeListener() {
+        @Override
+        public void onFocusChange(View v, boolean hasFocus) {
+            // Check whether this field contains focus by calling findFocus() instead of
+            // hasFocus(). The hasFocus() value is not necessarily up to date.
+            setHintColorDark(TextFieldsEditorView.this.findFocus() != null);
+            if (getEditorListener() != null) {
+                getEditorListener().onRequest(EditorListener.EDITOR_FOCUS_CHANGED);
+            }
+            // Rebuild the label spinner using the new colors.
+            rebuildLabel();
+        }
+    };
+
+    /**
+     * Set the hint color. If {@param isHintDark} is TRUE, then the hint color is set to a
+     * a darker color.
+     */
+    public void setHintColorDark(boolean isHintDark) {
+        if (mFieldEditTexts != null) {
+            for (EditText text : mFieldEditTexts) {
+                if (isHintDark) {
+                    text.setHintTextColor(mHintTextColor);
+                } else {
+                    text.setHintTextColor(mHintTextColorUnfocused);
+                }
+            }
+        }
+    }
+
     /**
      * Creates or removes the type/label button. Doesn't do anything if already correctly configured
      */
@@ -205,7 +237,7 @@
                     LayoutParams.WRAP_CONTENT));
             fieldView.setTextSize(TypedValue.COMPLEX_UNIT_PX,
                     getResources().getDimension(R.dimen.editor_form_text_size));
-            fieldView.setHintTextColor(mHintTextColor);
+            fieldView.setHintTextColor(mHintTextColorUnfocused);
             mFieldEditTexts[index] = fieldView;
             fieldView.setId(vig.getId(state, kind, entry, index));
             if (field.titleRes > 0) {
@@ -259,6 +291,7 @@
             });
 
             fieldView.setEnabled(isEnabled() && !readOnly);
+            fieldView.setOnFocusChangeListener(mTextFocusChangeListener);
 
             if (field.shortForm) {
                 hidePossible = true;