summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBrian Attwell <brianattwell@google.com>2014-10-30 11:11:56 -0700
committerBrian Attwell <brianattwell@google.com>2014-11-04 13:38:25 -0800
commit043fba637b421dcd554c634f769f0e883fb5ff8b (patch)
treee19ee507716fe891131e62b95559182f4ffe4a94
parent8f9d84fffbc32b50cf3133b2340b18d0510a6c6e (diff)
downloadpackages_apps_Contacts-043fba637b421dcd554c634f769f0e883fb5ff8b.tar.gz
packages_apps_Contacts-043fba637b421dcd554c634f769f0e883fb5ff8b.tar.bz2
packages_apps_Contacts-043fba637b421dcd554c634f769f0e883fb5ff8b.zip
Material design of common edit screen fields
The normal edit screen fields, such as phone number and location, have been updated to look like the new Material design mocks. I expect this to be the largest CL needed to finish b/18004959. Aspects of the Editor that haven't been touched in this CL - readonly editor - collapse nickname and phonetic name into StructuredNameEditorView. Then make sure the layout is correct - photo editor - Material insert/delete interpolators (maybe fast_out_slow_in) - account header Some complicated/weird parts of the CL: -KindSectionView no longer displays an "Add details" button. Instead it always shows an additional empty row for each mimeType. The logic that handles this is mostly inside #updateEmptyEditors(). A lot of code could be deleted from RawContactEditorView because of this. -LabeledEditorView's adapter displays TextView's inside Spinner. In order to make the TextViews look like EditTexts, I set the EditText's background (so the 9patch padding is used) and then later remove the background. -Instead of keeping an expansion_view_container in every single field, I only kept it where it was needed. As a result, I needed to add null checks into the TextFieldsEditorView base class. -I made an effort to reduce the depth of the view hierarchy and reduce the use of LinearLayout weights for performance reasons, when it was easy to do so Bug: 18004959 Change-Id: I5934ca189b66468834faf3bb995b172ae2f90bed
-rw-r--r--res/layout-sw600dp/text_fields_editor_view.xml51
-rw-r--r--res/layout/edit_date_picker.xml13
-rw-r--r--res/layout/edit_delete_button.xml2
-rw-r--r--res/layout/edit_field_list.xml5
-rw-r--r--res/layout/edit_field_list_with_anchor_view.xml2
-rw-r--r--res/layout/edit_simple_spinner_item.xml30
-rw-r--r--res/layout/edit_spinner.xml11
-rw-r--r--res/layout/event_field_editor_view.xml29
-rw-r--r--res/layout/item_group_membership.xml20
-rw-r--r--res/layout/item_kind_section.xml12
-rw-r--r--res/layout/organization_editor_view_switcher.xml50
-rw-r--r--res/layout/raw_contact_editor_view.xml70
-rw-r--r--res/layout/structured_name_editor_view.xml34
-rw-r--r--res/layout/text_fields_editor_view.xml31
-rw-r--r--res/values/colors.xml3
-rw-r--r--res/values/dimens.xml37
-rw-r--r--res/values/strings.xml3
-rw-r--r--res/values/styles.xml14
-rw-r--r--src/com/android/contacts/editor/EditorAnimator.java72
-rw-r--r--src/com/android/contacts/editor/GroupMembershipView.java5
-rw-r--r--src/com/android/contacts/editor/KindSectionView.java255
-rw-r--r--src/com/android/contacts/editor/LabeledEditorView.java20
-rw-r--r--src/com/android/contacts/editor/RawContactEditorView.java177
-rw-r--r--src/com/android/contacts/editor/TextFieldsEditorView.java98
24 files changed, 320 insertions, 724 deletions
diff --git a/res/layout-sw600dp/text_fields_editor_view.xml b/res/layout-sw600dp/text_fields_editor_view.xml
deleted file mode 100644
index c6b010b5d..000000000
--- a/res/layout-sw600dp/text_fields_editor_view.xml
+++ /dev/null
@@ -1,51 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2011 The Android Open Source Project
-
- 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.
--->
-
-<com.android.contacts.editor.TextFieldsEditorView
- xmlns:android="http://schemas.android.com/apk/res/android"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:orientation="vertical">
-
- <LinearLayout
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:layout_weight="1"
- android:orientation="horizontal"
- android:gravity="center_vertical">
-
- <include
- android:id="@+id/editors"
- layout="@layout/edit_field_list" />
-
- <include
- android:id="@+id/expansion_view_container"
- layout="@layout/edit_expansion_view"
- android:visibility="gone" />
-
- <include
- android:id="@+id/spinner"
- layout="@layout/edit_spinner"
- android:visibility="gone" />
-
- <include
- android:id="@+id/delete_button_container"
- layout="@layout/edit_delete_button"
- android:visibility="gone" />
-
- </LinearLayout>
-
-</com.android.contacts.editor.TextFieldsEditorView>
diff --git a/res/layout/edit_date_picker.xml b/res/layout/edit_date_picker.xml
index e2c4278b5..16bc5be54 100644
--- a/res/layout/edit_date_picker.xml
+++ b/res/layout/edit_date_picker.xml
@@ -16,19 +16,12 @@
-->
<!-- Button to select a date in the contact editor. -->
-
<Button
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/date_view"
style="@style/SpinnerButtonStyle"
- android:layout_width="0dip"
+ android:layout_width="match_parent"
android:layout_height="@dimen/editor_min_line_item_height"
android:layout_weight="1"
- android:gravity="center_vertical"
- android:layout_marginLeft="@dimen/editor_field_left_padding"
- android:layout_marginRight="@dimen/editor_field_right_padding"
- android:layout_marginStart="@dimen/editor_field_left_padding"
- android:layout_marginEnd="@dimen/editor_field_right_padding"
- android:textAppearance="?android:attr/textAppearanceMedium"
- android:paddingStart="12dip"
- android:paddingEnd="@dimen/editor_spinner_end_padding_workaround" />
+ android:textSize="@dimen/editor_form_text_size"
+ android:paddingRight="@dimen/editor_spinner_right_padding_workaround" />
diff --git a/res/layout/edit_delete_button.xml b/res/layout/edit_delete_button.xml
index 43f8ae656..eff2c51ba 100644
--- a/res/layout/edit_delete_button.xml
+++ b/res/layout/edit_delete_button.xml
@@ -23,7 +23,7 @@
android:layout_height="@dimen/editor_min_line_item_height"
android:layout_marginRight="2dip"
android:layout_marginEnd="2dip"
- android:layout_gravity="bottom">
+ android:layout_gravity="center_vertical">
<ImageView
android:id="@+id/delete_button"
android:layout_width="wrap_content"
diff --git a/res/layout/edit_field_list.xml b/res/layout/edit_field_list.xml
index 6922212e8..0073112d3 100644
--- a/res/layout/edit_field_list.xml
+++ b/res/layout/edit_field_list.xml
@@ -20,9 +20,6 @@
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/editors"
- android:layout_width="0dip"
- android:layout_weight="1"
+ android:layout_width="match_parent"
android:layout_height="wrap_content"
- android:paddingLeft="@dimen/editor_field_left_padding"
- android:paddingStart="@dimen/editor_field_left_padding"
android:orientation="vertical" />
diff --git a/res/layout/edit_field_list_with_anchor_view.xml b/res/layout/edit_field_list_with_anchor_view.xml
index ca1bdaf6f..a2c4cd129 100644
--- a/res/layout/edit_field_list_with_anchor_view.xml
+++ b/res/layout/edit_field_list_with_anchor_view.xml
@@ -22,8 +22,6 @@
android:layout_width="0dip"
android:layout_height="wrap_content"
android:layout_weight="1"
- android:paddingLeft="@dimen/editor_field_left_padding"
- android:paddingStart="@dimen/editor_field_left_padding"
android:orientation="vertical">
<LinearLayout
android:id="@+id/editors"
diff --git a/res/layout/edit_simple_spinner_item.xml b/res/layout/edit_simple_spinner_item.xml
new file mode 100644
index 000000000..6b78daceb
--- /dev/null
+++ b/res/layout/edit_simple_spinner_item.xml
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2014 The Android Open Source Project
+
+ 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.
+-->
+
+<!-- This TextView is displayed inside editor Spinners. In order to make this TextView get laid
+ out the same as an EditText, we use the EditText's background and gravity=center_vertical. The
+ EditText's background 9patch directly affects padding. -->
+<TextView xmlns:android="http://schemas.android.com/apk/res/android"
+ android:id="@android:id/text1"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:background="?android:attr/editTextBackground"
+ android:gravity="center_vertical"
+ android:paddingStart="0dp"
+ android:paddingEnd="0dp"
+ android:maxLines="1"
+ android:ellipsize="end" /> \ No newline at end of file
diff --git a/res/layout/edit_spinner.xml b/res/layout/edit_spinner.xml
index 81fb590d6..580b0010e 100644
--- a/res/layout/edit_spinner.xml
+++ b/res/layout/edit_spinner.xml
@@ -16,15 +16,14 @@
-->
<!-- Spinner for a field in the contact editor. -->
-
-<!-- Note: explicitly override the default left and right padding on spinner -->
<Spinner
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/spinner"
android:layout_gravity="bottom"
+ style="@android:style/Widget.Material.Spinner.Underlined"
+ android:dropDownWidth="@dimen/editor_type_label_dropdown_width"
android:layout_width="@dimen/editor_type_label_width"
android:layout_height="@dimen/editor_min_line_item_height"
- android:paddingLeft="0dip"
- android:paddingRight="10dip"
- android:paddingStart="0dip"
- android:paddingEnd="10dip" />
+ android:paddingBottom="0dp"
+ android:paddingTop="0dp"
+ android:paddingRight="@dimen/editor_spinner_right_padding_workaround" />
diff --git a/res/layout/event_field_editor_view.xml b/res/layout/event_field_editor_view.xml
index adca17e05..f4e5d2875 100644
--- a/res/layout/event_field_editor_view.xml
+++ b/res/layout/event_field_editor_view.xml
@@ -20,36 +20,29 @@
<com.android.contacts.editor.EventFieldEditorView
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
- android:layout_height="@dimen/editor_min_line_item_height"
- android:orientation="vertical">
+ android:layout_height="wrap_content"
+ android:orientation="horizontal">
<LinearLayout
- android:layout_width="match_parent"
+ android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
- android:orientation="horizontal"
- android:gravity="center_vertical">
+ android:orientation="vertical">
<include
android:id="@+id/date_view"
layout="@layout/edit_date_picker" />
- <Spinner
- android:id="@+id/spinner"
- android:layout_width="@dimen/editor_type_label_width"
- android:layout_height="match_parent"
- android:layout_gravity="bottom"
- android:paddingLeft="0dip"
- android:paddingRight="10dip"
- android:paddingStart="0dip"
- android:paddingEnd="10dip"
- android:visibility="gone"/>
-
<include
- android:id="@+id/delete_button_container"
- layout="@layout/edit_delete_button"
+ android:id="@+id/spinner"
+ layout="@layout/edit_spinner"
android:visibility="gone" />
</LinearLayout>
+ <include
+ android:id="@+id/delete_button_container"
+ layout="@layout/edit_delete_button"
+ android:visibility="gone" />
+
</com.android.contacts.editor.EventFieldEditorView>
diff --git a/res/layout/item_group_membership.xml b/res/layout/item_group_membership.xml
index fa447bb3b..8f9bc7ae4 100644
--- a/res/layout/item_group_membership.xml
+++ b/res/layout/item_group_membership.xml
@@ -19,10 +19,12 @@
android:id="@+id/group_membership_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"
- android:orientation="vertical">
+ android:orientation="horizontal">
- <include
- layout="@layout/edit_kind_title" />
+ <ImageView
+ android:id="@+id/kind_icon"
+ android:src="@drawable/ic_people_black_24dp"
+ style="@style/EditKindIconStyle" />
<Button
style="@style/SpinnerButtonStyle"
@@ -30,14 +32,10 @@
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:minHeight="@dimen/editor_min_line_item_height"
- android:layout_marginLeft="@dimen/editor_field_left_padding"
- android:layout_marginRight="@dimen/editor_field_left_padding"
- android:layout_marginStart="@dimen/editor_field_left_padding"
- android:layout_marginEnd="@dimen/editor_field_left_padding"
- android:textAppearance="?android:attr/textAppearanceMedium"
- android:gravity="start|center_vertical"
+ android:textSize="@dimen/editor_form_text_size"
android:focusable="true"
- android:paddingStart="12dip"
- android:paddingEnd="@dimen/editor_spinner_end_padding_workaround"/>
+ android:layout_marginEnd="@dimen/editor_delete_button_size"
+ android:layout_marginBottom="@dimen/editor_padding_between_editor_views"
+ android:paddingRight="@dimen/editor_spinner_right_padding_workaround"/>
</com.android.contacts.editor.GroupMembershipView>
diff --git a/res/layout/item_kind_section.xml b/res/layout/item_kind_section.xml
index 157ca1cc1..d62523b0a 100644
--- a/res/layout/item_kind_section.xml
+++ b/res/layout/item_kind_section.xml
@@ -20,11 +20,11 @@
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
- android:orientation="vertical">
+ android:orientation="horizontal">
- <include
- android:id="@+id/kind_title_layout"
- layout="@layout/edit_kind_title" />
+ <ImageView
+ android:id="@+id/kind_icon"
+ style="@style/EditKindIconStyle" />
<LinearLayout
android:id="@+id/kind_editors"
@@ -32,8 +32,4 @@
android:layout_height="wrap_content"
android:orientation="vertical" />
- <include
- android:id="@+id/add_field_footer"
- layout="@layout/edit_add_field" />
-
</com.android.contacts.editor.KindSectionView> \ No newline at end of file
diff --git a/res/layout/organization_editor_view_switcher.xml b/res/layout/organization_editor_view_switcher.xml
deleted file mode 100644
index 07d1cd8ed..000000000
--- a/res/layout/organization_editor_view_switcher.xml
+++ /dev/null
@@ -1,50 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2011 The Android Open Source Project
-
- 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.
--->
-
-<!--
- Layout of "organization" field in contact editor which either shows the "add
- organization" button or a container (which should be populated with the actual
- list of edit text fields).
--->
-
-<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
- android:layout_width="match_parent"
- android:layout_height="wrap_content">
-
- <TextView
- android:id="@+id/add_organization_button"
- android:layout_width="match_parent"
- android:layout_height="48dip"
- android:paddingLeft="@dimen/editor_add_field_label_left_padding"
- android:paddingRight="16dip"
- android:paddingStart="@dimen/editor_add_field_label_left_padding"
- android:paddingEnd="16dip"
- android:gravity="center_vertical"
- android:textAppearance="?android:attr/textAppearanceMedium"
- android:textColor="?android:attr/textColorSecondary"
- android:background="?android:attr/selectableItemBackground"
- android:text="@string/add_organization"
- android:focusable="true"
- android:clickable="true"/>
-
- <!-- This is later populated with the actual editable text fields for "organization" -->
- <FrameLayout
- android:id="@+id/container"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:visibility="gone"/>
-
-</FrameLayout> \ No newline at end of file
diff --git a/res/layout/raw_contact_editor_view.xml b/res/layout/raw_contact_editor_view.xml
index 981160264..03996b515 100644
--- a/res/layout/raw_contact_editor_view.xml
+++ b/res/layout/raw_contact_editor_view.xml
@@ -16,64 +16,38 @@
<com.android.contacts.editor.RawContactEditorView
xmlns:android="http://schemas.android.com/apk/res/android"
+ android:id="@+id/body"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
- android:paddingTop="@dimen/editor_padding_top">
+ android:paddingTop="@dimen/editor_padding_top" >
<include
layout="@layout/editor_account_header_with_dropdown" />
- <LinearLayout
- android:id="@+id/body"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:orientation="vertical">
-
- <LinearLayout
- android:layout_height="wrap_content"
- android:layout_width="match_parent"
- android:orientation="horizontal"
- android:paddingTop="8dip">
-
- <LinearLayout
- android:layout_height="wrap_content"
- android:layout_width="0dip"
- android:layout_weight="1"
- android:orientation="vertical">
-
- <include
- android:id="@+id/edit_name"
- layout="@layout/structured_name_editor_view" />
-
- <include
- android:id="@+id/edit_phonetic_name"
- layout="@layout/phonetic_name_editor_view" />
+ <Space
+ android:layout_height="8dip"
+ android:layout_width="match_parent" />
- </LinearLayout>
-
- <include
- android:id="@+id/edit_photo"
- android:layout_marginRight="8dip"
- android:layout_marginEnd="8dip"
- layout="@layout/item_photo_editor" />
+ <include
+ android:id="@+id/edit_name"
+ layout="@layout/structured_name_editor_view" />
- </LinearLayout>
+ <include
+ android:id="@+id/edit_phonetic_name"
+ layout="@layout/phonetic_name_editor_view" />
- <LinearLayout
- android:id="@+id/sect_fields"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:orientation="vertical"
- android:layout_marginBottom="16dip"/>
+ <include
+ android:id="@+id/edit_photo"
+ android:layout_marginRight="8dip"
+ android:layout_marginEnd="8dip"
+ layout="@layout/item_photo_editor" />
- <Button
- android:id="@+id/button_add_field"
- android:text="@string/add_field"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_gravity="center"
- android:layout_marginBottom="32dip"/>
+ <LinearLayout
+ android:id="@+id/sect_fields"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:orientation="vertical"
+ android:layout_marginBottom="16dip"/>
- </LinearLayout>
</com.android.contacts.editor.RawContactEditorView>
diff --git a/res/layout/structured_name_editor_view.xml b/res/layout/structured_name_editor_view.xml
index 6320aa52b..fc57159e1 100644
--- a/res/layout/structured_name_editor_view.xml
+++ b/res/layout/structured_name_editor_view.xml
@@ -20,31 +20,31 @@
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:minHeight="@dimen/editor_min_line_item_height"
- android:orientation="vertical">
+ android:orientation="horizontal">
+ <!-- This isn't used in StructuredNameEditorView. It is only included so that
+ StructuredNameEditorView's base classes don't need extra null checks. -->
<include
android:id="@+id/spinner"
layout="@layout/edit_spinner"
android:visibility="gone" />
- <LinearLayout
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:orientation="horizontal">
+ <ImageView
+ android:id="@+id/kind_icon"
+ android:src="@drawable/ic_person_black_24dp"
+ style="@style/EditKindIconStyle" />
- <include
- layout="@layout/edit_field_list_with_anchor_view" />
-
- <include
- android:id="@+id/expansion_view_container"
- layout="@layout/name_edit_expansion_view"
- android:visibility="gone" />
+ <include
+ layout="@layout/edit_field_list_with_anchor_view" />
- <include
- android:id="@+id/delete_button_container"
- layout="@layout/edit_delete_button"
- android:visibility="gone" />
+ <include
+ android:id="@+id/expansion_view_container"
+ layout="@layout/name_edit_expansion_view"
+ android:visibility="gone" />
- </LinearLayout>
+ <include
+ android:id="@+id/delete_button_container"
+ layout="@layout/edit_delete_button"
+ android:visibility="gone" />
</com.android.contacts.editor.StructuredNameEditorView>
diff --git a/res/layout/text_fields_editor_view.xml b/res/layout/text_fields_editor_view.xml
index 5ae83c64c..dc3a31204 100644
--- a/res/layout/text_fields_editor_view.xml
+++ b/res/layout/text_fields_editor_view.xml
@@ -19,33 +19,30 @@
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
- android:orientation="vertical">
+ android:orientation="horizontal">
<LinearLayout
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
+ android:layout_width="0dp"
android:layout_weight="1"
- android:orientation="horizontal"
- android:gravity="center_vertical">
-
- <include
- layout="@layout/edit_field_list_with_anchor_view" />
+ android:layout_height="wrap_content"
+ android:orientation="vertical">
- <include
- android:id="@+id/expansion_view_container"
- layout="@layout/edit_expansion_view"
- android:visibility="gone" />
+ <LinearLayout
+ android:id="@+id/editors"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:orientation="vertical" />
<include
android:id="@+id/spinner"
layout="@layout/edit_spinner"
android:visibility="gone" />
- <include
- android:id="@+id/delete_button_container"
- layout="@layout/edit_delete_button"
- android:visibility="gone" />
-
</LinearLayout>
+ <include
+ android:id="@+id/delete_button_container"
+ layout="@layout/edit_delete_button"
+ android:visibility="gone" />
+
</com.android.contacts.editor.TextFieldsEditorView>
diff --git a/res/values/colors.xml b/res/values/colors.xml
index 985a4e5c7..daea14bca 100644
--- a/res/values/colors.xml
+++ b/res/values/colors.xml
@@ -54,4 +54,7 @@
<!-- Background color of pinned header items. -->
<color name="list_item_pinned_header_color">@color/background_primary</color>
+
+ <!-- Color of the mime-type icons inside the editor. 50% black. -->
+ <color name="editor_icon_color">#7f7f7f</color>
</resources>
diff --git a/res/values/dimens.xml b/res/values/dimens.xml
index 857045c46..69b56dcf4 100644
--- a/res/values/dimens.xml
+++ b/res/values/dimens.xml
@@ -37,27 +37,34 @@
<!-- Minimum height of a row in the Editor -->
<dimen name="editor_min_line_item_height">48dip</dimen>
- <!-- Top padding of an EditText in the Editor -->
- <dimen name="editor_text_field_top_padding">8dip</dimen>
+ <!-- The height and width of the delete button should be the same size as an editor row -->
+ <dimen name="editor_delete_button_size">@dimen/editor_min_line_item_height</dimen>
- <!-- Bottom padding of an EditText in the Editor -->
- <dimen name="editor_text_field_bottom_padding">7dip</dimen>
+ <!-- Top margin applied to mime-type icons inside the editor. This is needed to give the
+ appearance that the icons are top aligned with the text, since visible text doesn't
+ start at the very top of TextViews. -->
+ <dimen name="editor_kind_icon_top_margin">9dp</dimen>
- <!-- Right padding of a field in the Editor -->
- <dimen name="editor_field_right_padding">4dip</dimen>
+ <!-- RHS padding added to spinners in the editor. This separates the spinner text from the
+ spinner graphic since b/18194928 causes the spinner to always be on the RHS.
+ In LTR mode this shouldn't have an observable affect. We set paddingRight instead of
+ drawablePadding since the spinner graphic is not a normal drawable. -->
+ <dimen name="editor_spinner_right_padding_workaround">24dip</dimen>
- <!-- Left padding of a field in the Editor -->
- <dimen name="editor_field_left_padding">4dip</dimen>
+ <!-- Size of input form text inside the contact editor -->
+ <dimen name="editor_form_text_size">16sp</dimen>
- <!-- End padding added to spinners in the editor. This separates the spinner text from the
- spinner graphic when Button gravity is incorrectly set in RTL mode
- (see framework bug b/17011078. In LTR mode this shouldn't have an observable affect.
- We set paddingEnd instead of drawablePadding since the spinner graphic is not a normal
- drawable. -->
- <dimen name="editor_spinner_end_padding_workaround">24dip</dimen>
+ <!-- Width and height of the mime-type icons inside the editor -->
+ <dimen name="editor_kind_icon_size">24dp</dimen>
+
+ <!-- Padding below every editor view, such as LabeledEditorView -->
+ <dimen name="editor_padding_between_editor_views">24dp</dimen>
<!-- Width of the Type-Label in the Editor -->
- <dimen name="editor_type_label_width">100dip</dimen>
+ <dimen name="editor_type_label_width">150dip</dimen>
+
+ <!-- Width of the drop down that appears when you click on the Type-Label spinner in the editor -->
+ <dimen name="editor_type_label_dropdown_width">150dp</dimen>
<!-- Left padding of the label in the add field button for the contact editor -->
<dimen name="editor_add_field_label_left_padding">16dip</dimen>
diff --git a/res/values/strings.xml b/res/values/strings.xml
index e8b954ecc..bd0391746 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -426,9 +426,6 @@
<!-- Label to clear all selection in multiple picker -->
<string name="menu_select_none">"Unselect all"</string>
- <!-- The add field button shown in the editor under each editable Raw Contact [CHAR LIMIT=30] -->
- <string name="add_field">Add another field</string>
-
<!-- The button to add another entry of a specific data type (i.e. email, phone, address) to a contact in the Raw Contact Editor [CHAR LIMIT=22] -->
<string name="add_new_entry_for_section">Add new</string>
diff --git a/res/values/styles.xml b/res/values/styles.xml
index d66cf4e19..1261a7a25 100644
--- a/res/values/styles.xml
+++ b/res/values/styles.xml
@@ -284,11 +284,14 @@
<item name="android:layout_height">wrap_content</item>
</style>
- <style name="SpinnerButtonStyle" parent="@android:style/Widget.Material.Spinner">
+ <style name="SpinnerButtonStyle" parent="@android:style/Widget.Material.Spinner.Underlined">
<!-- When applying the spinner style to a Button we need to disable the shadow animation
on the button since the spinner background is transparent. Otherwise the spinner-button
will look ridiculous. -->
<item name="android:stateListAnimator">@null</item>
+ <!-- We want our spinner's to use the same gravity as an EditText, so that they look
+ visually consistent with other controls in our forms -->
+ <item name="android:gravity">start|center_vertical</item>
</style>
<style name="EditKindSeparatorTextViewStyle" parent="ContactListSeparatorTextViewStyle">
@@ -308,4 +311,13 @@
<style name="ContactsAlertDialogTheme" parent="@android:style/Theme.Material.Light.Dialog">
<item name="android:colorAccent">@color/primary_color</item>
</style>
+
+ <style name="EditKindIconStyle">
+ <item name="android:layout_width">24dp</item>
+ <item name="android:layout_height">24dp</item>
+ <item name="android:tint">@color/editor_icon_color</item>
+ <item name="android:layout_marginStart">16dp</item>
+ <item name="android:layout_marginEnd">32dp</item>
+ <item name="android:layout_marginTop">@dimen/editor_kind_icon_top_margin</item>
+ </style>
</resources>
diff --git a/src/com/android/contacts/editor/EditorAnimator.java b/src/com/android/contacts/editor/EditorAnimator.java
index 7e85d8be2..507e094ba 100644
--- a/src/com/android/contacts/editor/EditorAnimator.java
+++ b/src/com/android/contacts/editor/EditorAnimator.java
@@ -115,43 +115,7 @@ public class EditorAnimator {
});
}
- public void expandOrganization(final View addOrganizationButton,
- final ViewGroup organizationSectionViewContainer) {
- mRunner.endOldAnimation();
- // Make the new controls visible and do one layout pass (so that we can measure)
- organizationSectionViewContainer.setVisibility(View.VISIBLE);
- organizationSectionViewContainer.setAlpha(0.0f);
- organizationSectionViewContainer.requestFocus();
- SchedulingUtils.doAfterLayout(addOrganizationButton, new Runnable() {
- @Override
- public void run() {
- // How many pixels extra do we need?
- final int offset = organizationSectionViewContainer.getHeight() -
- addOrganizationButton.getHeight();
- final List<Animator> animators = Lists.newArrayList();
-
- // Fade out
- final ObjectAnimator fadeOutAnimator = ObjectAnimator.ofFloat(
- addOrganizationButton, View.ALPHA, 1.0f, 0.0f);
- fadeOutAnimator.setDuration(200);
- animators.add(fadeOutAnimator);
-
- // Translations
- final List<View> viewsToMove = getViewsBelowOf(organizationSectionViewContainer);
- translateViews(animators, viewsToMove, -offset, 0.0f, 0, 200);
- // Fade in
- final ObjectAnimator fadeInAnimator = ObjectAnimator.ofFloat(
- organizationSectionViewContainer, View.ALPHA, 0.0f, 1.0f);
- fadeInAnimator.setDuration(200);
- fadeInAnimator.setStartDelay(200);
- animators.add(fadeInAnimator);
-
- mRunner.run(animators);
- }
- });
- }
-
- public void showAddFieldFooter(final View view) {
+ public void showFieldFooter(final View view) {
mRunner.endOldAnimation();
if (view.getVisibility() == View.VISIBLE) return;
// Make the new controls visible and do one layout pass (so that we can measure)
@@ -181,40 +145,6 @@ public class EditorAnimator {
});
}
- public void hideAddFieldFooter(final View victim) {
- mRunner.endOldAnimation();
- if (victim.getVisibility() == View.GONE) return;
- final int offset = victim.getHeight();
-
- final List<View> viewsToMove = getViewsBelowOf(victim);
- final List<Animator> animators = Lists.newArrayList();
-
- // Fade out
- final ObjectAnimator fadeOutAnimator =
- ObjectAnimator.ofFloat(victim, View.ALPHA, 1.0f, 0.0f);
- fadeOutAnimator.setDuration(200);
- animators.add(fadeOutAnimator);
-
- // Translations
- translateViews(animators, viewsToMove, 0.0f, -offset, 100, 200);
-
- // Combine
- mRunner.run(animators, new AnimatorListenerAdapter() {
- @Override
- public void onAnimationEnd(Animator animation) {
- // Clean up: Remove all the translations
- for (int i = 0; i < viewsToMove.size(); i++) {
- final View view = viewsToMove.get(i);
- view.setTranslationY(0.0f);
- }
-
- // Restore alpha (for next time), but hide the view for good now
- victim.setAlpha(1.0f);
- victim.setVisibility(View.GONE);
- }
- });
- }
-
/**
* Creates a translation-animation for the given views
*/
diff --git a/src/com/android/contacts/editor/GroupMembershipView.java b/src/com/android/contacts/editor/GroupMembershipView.java
index bcea53dcf..5752a4796 100644
--- a/src/com/android/contacts/editor/GroupMembershipView.java
+++ b/src/com/android/contacts/editor/GroupMembershipView.java
@@ -30,6 +30,7 @@ import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.ArrayAdapter;
import android.widget.CheckedTextView;
+import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.ListPopupWindow;
import android.widget.ListView;
@@ -173,8 +174,8 @@ public class GroupMembershipView extends LinearLayout
public void setKind(DataKind kind) {
mKind = kind;
- TextView kindTitle = (TextView) findViewById(R.id.kind_title);
- kindTitle.setText(getResources().getString(kind.titleRes).toUpperCase());
+ final ImageView imageView = (ImageView) findViewById(R.id.kind_icon);
+ imageView.setContentDescription(getResources().getString(kind.titleRes));
}
public void setGroupMetaData(Cursor groupMetaData) {
diff --git a/src/com/android/contacts/editor/KindSectionView.java b/src/com/android/contacts/editor/KindSectionView.java
index 261286e47..24d4ee8ff 100644
--- a/src/com/android/contacts/editor/KindSectionView.java
+++ b/src/com/android/contacts/editor/KindSectionView.java
@@ -17,14 +17,27 @@
package com.android.contacts.editor;
import android.content.Context;
+import android.graphics.drawable.Drawable;
+import android.provider.Contacts.GroupMembership;
+import android.provider.ContactsContract.CommonDataKinds.Email;
+import android.provider.ContactsContract.CommonDataKinds.Event;
+import android.provider.ContactsContract.CommonDataKinds.Im;
+import android.provider.ContactsContract.CommonDataKinds.Note;
+import android.provider.ContactsContract.CommonDataKinds.Organization;
+import android.provider.ContactsContract.CommonDataKinds.Phone;
+import android.provider.ContactsContract.CommonDataKinds.Photo;
+import android.provider.ContactsContract.CommonDataKinds.Relation;
+import android.provider.ContactsContract.CommonDataKinds.SipAddress;
+import android.provider.ContactsContract.CommonDataKinds.StructuredPostal;
+import android.provider.ContactsContract.CommonDataKinds.Website;
import android.provider.ContactsContract.Data;
import android.text.TextUtils;
import android.util.AttributeSet;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
+import android.widget.ImageView;
import android.widget.LinearLayout;
-import android.widget.TextView;
import com.android.contacts.R;
import com.android.contacts.editor.Editor.EditorListener;
@@ -44,10 +57,8 @@ import java.util.List;
public class KindSectionView extends LinearLayout implements EditorListener {
private static final String TAG = "KindSectionView";
- private TextView mTitle;
private ViewGroup mEditors;
- private View mAddFieldFooter;
- private String mTitleString;
+ private ImageView mIcon;
private DataKind mKind;
private RawContactDelta mState;
@@ -57,8 +68,6 @@ public class KindSectionView extends LinearLayout implements EditorListener {
private LayoutInflater mInflater;
- private final ArrayList<Runnable> mRunWhenWindowFocused = new ArrayList<Runnable>(1);
-
public KindSectionView(Context context) {
this(context, null);
}
@@ -77,11 +86,7 @@ public class KindSectionView extends LinearLayout implements EditorListener {
}
}
- if (enabled && !mReadOnly) {
- mAddFieldFooter.setVisibility(View.VISIBLE);
- } else {
- mAddFieldFooter.setVisibility(View.GONE);
- }
+ updateEmptyEditors(/* shouldAnimate = */ true);
}
public boolean isReadOnly() {
@@ -96,17 +101,8 @@ public class KindSectionView extends LinearLayout implements EditorListener {
mInflater = (LayoutInflater) mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
- mTitle = (TextView) findViewById(R.id.kind_title);
mEditors = (ViewGroup) findViewById(R.id.kind_editors);
- mAddFieldFooter = findViewById(R.id.add_field_footer);
- mAddFieldFooter.setOnClickListener(new OnClickListener() {
- @Override
- public void onClick(View v) {
- // Setup click listener to add an empty field when the footer is clicked.
- mAddFieldFooter.setVisibility(View.GONE);
- addItem();
- }
- });
+ mIcon = (ImageView) findViewById(R.id.kind_icon);
}
@Override
@@ -126,7 +122,7 @@ public class KindSectionView extends LinearLayout implements EditorListener {
// If a field has become empty or non-empty, then check if another row
// can be added dynamically.
if (request == FIELD_TURNED_EMPTY || request == FIELD_TURNED_NON_EMPTY) {
- updateAddFooterVisible(true);
+ updateEmptyEditors(/* shouldAnimate = */ true);
}
}
@@ -139,28 +135,21 @@ public class KindSectionView extends LinearLayout implements EditorListener {
setId(mViewIdGenerator.getId(state, kind, null, ViewIdGenerator.NO_VIEW_INDEX));
// TODO: handle resources from remote packages
- mTitleString = (kind.titleRes == -1 || kind.titleRes == 0)
+ final String titleString = (kind.titleRes == -1 || kind.titleRes == 0)
? ""
: getResources().getString(kind.titleRes);
- mTitle.setText(mTitleString);
+ mIcon.setContentDescription(titleString);
- rebuildFromState();
- updateAddFooterVisible(false);
- updateSectionVisible();
- }
-
- public String getTitle() {
- return mTitleString;
- }
+ mIcon.setImageDrawable(getMimeTypeDrawable(kind.mimeType));
- public void setTitleVisible(boolean visible) {
- findViewById(R.id.kind_title_layout).setVisibility(visible ? View.VISIBLE : View.GONE);
+ rebuildFromState();
+ updateEmptyEditors(/* shouldAnimate = */ false);
}
/**
* Build editors for all current {@link #mState} rows.
*/
- public void rebuildFromState() {
+ private void rebuildFromState() {
// Remove any existing editors
mEditors.removeAllViews();
@@ -222,48 +211,49 @@ public class KindSectionView extends LinearLayout implements EditorListener {
return true;
}
- private void updateSectionVisible() {
- setVisibility(getEditorCount() != 0 ? VISIBLE : GONE);
- }
-
- protected void updateAddFooterVisible(boolean animate) {
- if (!mReadOnly && (mKind.typeOverallMax != 1)) {
- // First determine whether there are any existing empty editors.
- updateEmptyEditors();
- // If there are no existing empty editors and it's possible to add
- // another field, then make the "add footer" field visible.
- if (!hasEmptyEditor() && RawContactModifier.canInsert(mState, mKind)) {
- if (animate) {
- EditorAnimator.getInstance().showAddFieldFooter(mAddFieldFooter);
- } else {
- mAddFieldFooter.setVisibility(View.VISIBLE);
- }
- return;
- }
- }
- if (animate) {
- EditorAnimator.getInstance().hideAddFieldFooter(mAddFieldFooter);
- } else {
- mAddFieldFooter.setVisibility(View.GONE);
- }
- }
-
/**
* Updates the editors being displayed to the user removing extra empty
* {@link Editor}s, so there is only max 1 empty {@link Editor} view at a time.
*/
- private void updateEmptyEditors() {
- List<View> emptyEditors = getEmptyEditors();
+ private void updateEmptyEditors(boolean shouldAnimate) {
+
+ final List<View> emptyEditors = getEmptyEditors();
// If there is more than 1 empty editor, then remove it from the list of editors.
if (emptyEditors.size() > 1) {
- for (View emptyEditorView : emptyEditors) {
- // If no child {@link View}s are being focused on within
- // this {@link View}, then remove this empty editor.
+ for (final View emptyEditorView : emptyEditors) {
+ // If no child {@link View}s are being focused on within this {@link View}, then
+ // remove this empty editor. We can assume that at least one empty editor has focus.
+ // The only way to get two empty editors is by deleting characters from a non-empty
+ // editor, in which case this editor has focus.
if (emptyEditorView.findFocus() == null) {
- mEditors.removeView(emptyEditorView);
+ final Editor editor = (Editor) emptyEditorView;
+ if (shouldAnimate) {
+ editor.deleteEditor();
+ } else {
+ mEditors.removeView(emptyEditorView);
+ }
}
}
+ } else if (mKind == null) {
+ // There is nothing we can do.
+ return;
+ } else if (isReadOnly()) {
+ // We don't show empty editors for read only data kinds.
+ return;
+ } else if (mKind.typeOverallMax == getEditorCount() && mKind.typeOverallMax != 0) {
+ // We have already reached the maximum number of editors. Lets not add any more.
+ return;
+ } else if (emptyEditors.size() == 1) {
+ // We have already reached the maximum number of empty editors. Lets not add any more.
+ return;
+ } else {
+ final ValuesDelta values = RawContactModifier.insertChild(mState, mKind);
+ final View newField = createEditorView(values);
+ if (shouldAnimate) {
+ newField.setVisibility(View.GONE);
+ EditorAnimator.getInstance().showFieldFooter(newField);
+ }
}
}
@@ -281,110 +271,45 @@ public class KindSectionView extends LinearLayout implements EditorListener {
return emptyEditorViews;
}
- /**
- * Returns true if one of the editors has all of its fields empty, or false
- * otherwise.
- */
- private boolean hasEmptyEditor() {
- return getEmptyEditors().size() > 0;
- }
-
- /**
- * Returns true if all editors are empty.
- */
- public boolean isEmpty() {
- for (int i = 0; i < mEditors.getChildCount(); i++) {
- View view = mEditors.getChildAt(i);
- if (!((Editor) view).isEmpty()) {
- return false;
- }
- }
- return true;
- }
-
- /**
- * Extends superclass implementation to also run tasks
- * enqueued by {@link #runWhenWindowFocused}.
- */
- @Override
- public void onWindowFocusChanged(boolean hasWindowFocus) {
- super.onWindowFocusChanged(hasWindowFocus);
- if (hasWindowFocus) {
- for (Runnable r: mRunWhenWindowFocused) {
- r.run();
- }
- mRunWhenWindowFocused.clear();
- }
+ public int getEditorCount() {
+ return mEditors.getChildCount();
}
- /**
- * Depending on whether we are in the currently-focused window, either run
- * the argument immediately, or stash it until our window becomes focused.
- */
- private void runWhenWindowFocused(Runnable r) {
- if (hasWindowFocus()) {
- r.run();
- } else {
- mRunWhenWindowFocused.add(r);
- }
+ public DataKind getKind() {
+ return mKind;
}
/**
- * Simple wrapper around {@link #runWhenWindowFocused}
- * to ensure that it runs in the UI thread.
+ * Return an icon that represents {@param mimeType}.
*/
- private void postWhenWindowFocused(final Runnable r) {
- post(new Runnable() {
- @Override
- public void run() {
- runWhenWindowFocused(r);
- }
- });
- }
-
- public void addItem() {
- ValuesDelta values = null;
- // If this is a list, we can freely add. If not, only allow adding the first.
- if (mKind.typeOverallMax == 1) {
- if (getEditorCount() == 1) {
- return;
- }
-
- // If we already have an item, just make it visible
- ArrayList<ValuesDelta> entries = mState.getMimeEntries(mKind.mimeType);
- if (entries != null && entries.size() > 0) {
- values = entries.get(0);
- }
+ private Drawable getMimeTypeDrawable(String mimeType) {
+ switch (mimeType) {
+ case StructuredPostal.CONTENT_ITEM_TYPE:
+ return getResources().getDrawable(R.drawable.ic_place_24dp);
+ case SipAddress.CONTENT_ITEM_TYPE:
+ return getResources().getDrawable(R.drawable.ic_dialer_sip_black_24dp);
+ case Phone.CONTENT_ITEM_TYPE:
+ return getResources().getDrawable(R.drawable.ic_phone_24dp);
+ case Im.CONTENT_ITEM_TYPE:
+ return getResources().getDrawable(R.drawable.ic_message_24dp);
+ case Event.CONTENT_ITEM_TYPE:
+ return getResources().getDrawable(R.drawable.ic_event_24dp);
+ case Email.CONTENT_ITEM_TYPE:
+ return getResources().getDrawable(R.drawable.ic_email_24dp);
+ case Website.CONTENT_ITEM_TYPE:
+ return getResources().getDrawable(R.drawable.ic_public_black_24dp);
+ case Photo.CONTENT_ITEM_TYPE:
+ return getResources().getDrawable(R.drawable.ic_camera_alt_black_24dp);
+ case GroupMembership.CONTENT_ITEM_TYPE:
+ return getResources().getDrawable(R.drawable.ic_people_black_24dp);
+ case Organization.CONTENT_ITEM_TYPE:
+ return getResources().getDrawable(R.drawable.ic_business_black_24dp);
+ case Note.CONTENT_ITEM_TYPE:
+ return getResources().getDrawable(R.drawable.ic_insert_comment_black_24dp);
+ case Relation.CONTENT_ITEM_TYPE:
+ return getResources().getDrawable(R.drawable.ic_circles_extended_black_24dp);
+ default:
+ return null;
}
-
- // Insert a new child, create its view and set its focus
- if (values == null) {
- values = RawContactModifier.insertChild(mState, mKind);
- }
-
- final View newField = createEditorView(values);
- if (newField instanceof Editor) {
- postWhenWindowFocused(new Runnable() {
- @Override
- public void run() {
- newField.requestFocus();
- ((Editor)newField).editNewlyAddedField();
- }
- });
- }
-
- // Hide the "add field" footer because there is now a blank field.
- mAddFieldFooter.setVisibility(View.GONE);
-
- // Ensure we are visible
- updateSectionVisible();
- }
-
- public int getEditorCount() {
- return mEditors.getChildCount();
- }
-
- public DataKind getKind() {
- return mKind;
}
}
diff --git a/src/com/android/contacts/editor/LabeledEditorView.java b/src/com/android/contacts/editor/LabeledEditorView.java
index e0524ce29..c28006229 100644
--- a/src/com/android/contacts/editor/LabeledEditorView.java
+++ b/src/com/android/contacts/editor/LabeledEditorView.java
@@ -25,10 +25,9 @@ import android.os.Bundle;
import android.os.Handler;
import android.text.Editable;
import android.text.TextUtils;
-import android.text.TextUtils.TruncateAt;
import android.text.TextWatcher;
import android.util.AttributeSet;
-import android.view.Gravity;
+import android.util.TypedValue;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
@@ -160,6 +159,9 @@ public abstract class LabeledEditorView extends LinearLayout implements Editor,
});
}
});
+
+ setPadding(getPaddingLeft(), getPaddingTop(), getPaddingRight(),
+ (int) getResources().getDimension(R.dimen.editor_padding_between_editor_views));
}
@Override
@@ -551,8 +553,12 @@ public abstract class LabeledEditorView extends LinearLayout implements Editor,
@Override
public View getView(int position, View convertView, ViewGroup parent) {
- return createViewFromResource(
- position, convertView, parent, android.R.layout.simple_spinner_item);
+ final View 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);
+ return view;
}
@Override
@@ -567,11 +573,9 @@ public abstract class LabeledEditorView extends LinearLayout implements Editor,
if (convertView == null) {
textView = (TextView) mInflater.inflate(resource, parent, false);
- textView.setAllCaps(true);
- textView.setGravity(Gravity.END | Gravity.CENTER_VERTICAL);
- textView.setTextAppearance(mContext, android.R.style.TextAppearance_Small);
+ textView.setTextSize(TypedValue.COMPLEX_UNIT_PX, getResources().getDimension(
+ R.dimen.editor_form_text_size));
textView.setTextColor(mTextColor);
- textView.setEllipsize(TruncateAt.MIDDLE);
} else {
textView = (TextView) convertView;
}
diff --git a/src/com/android/contacts/editor/RawContactEditorView.java b/src/com/android/contacts/editor/RawContactEditorView.java
index 39fe95ae9..f0fbc4abe 100644
--- a/src/com/android/contacts/editor/RawContactEditorView.java
+++ b/src/com/android/contacts/editor/RawContactEditorView.java
@@ -21,7 +21,7 @@ import android.database.Cursor;
import android.os.Bundle;
import android.os.Parcelable;
import android.provider.ContactsContract.CommonDataKinds.GroupMembership;
-import android.provider.ContactsContract.CommonDataKinds.Organization;
+import android.provider.ContactsContract.CommonDataKinds.Nickname;
import android.provider.ContactsContract.CommonDataKinds.Photo;
import android.provider.ContactsContract.CommonDataKinds.StructuredName;
import android.provider.ContactsContract.Contacts;
@@ -29,13 +29,9 @@ import android.provider.ContactsContract.Data;
import android.text.TextUtils;
import android.util.AttributeSet;
import android.view.LayoutInflater;
-import android.view.Menu;
-import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
-import android.widget.Button;
import android.widget.ImageView;
-import android.widget.PopupMenu;
import android.widget.TextView;
import com.android.contacts.GroupMetaDataLoader;
@@ -62,7 +58,6 @@ import java.util.ArrayList;
* {@link RawContactModifier} to ensure that {@link AccountType} are enforced.
*/
public class RawContactEditorView extends BaseRawContactEditorView {
- private static final String KEY_ORGANIZATION_VIEW_EXPANDED = "organizationViewExpanded";
private static final String KEY_SUPER_INSTANCE_STATE = "superInstanceState";
private LayoutInflater mInflater;
@@ -71,27 +66,18 @@ public class RawContactEditorView extends BaseRawContactEditorView {
private PhoneticNameEditorView mPhoneticName;
private GroupMembershipView mGroupMembershipView;
- private ViewGroup mOrganizationSectionViewContainer;
- private View mAddOrganizationButton;
- private View mOrganizationView;
- private boolean mOrganizationViewExpanded = false;
-
private ViewGroup mFields;
private ImageView mAccountIcon;
private TextView mAccountTypeTextView;
private TextView mAccountNameTextView;
- private Button mAddFieldButton;
-
private long mRawContactId = -1;
private boolean mAutoAddToDefaultGroup = true;
private Cursor mGroupMetaData;
private DataKind mGroupMembershipKind;
private RawContactDelta mState;
- private boolean mPhoneticNameAdded;
-
public RawContactEditorView(Context context) {
super(context);
}
@@ -127,8 +113,6 @@ public class RawContactEditorView extends BaseRawContactEditorView {
if (mGroupMembershipView != null) {
mGroupMembershipView.setEnabled(enabled);
}
-
- mAddFieldButton.setEnabled(enabled);
}
@Override
@@ -148,27 +132,11 @@ public class RawContactEditorView extends BaseRawContactEditorView {
mAccountIcon = (ImageView) findViewById(R.id.account_icon);
mAccountTypeTextView = (TextView) findViewById(R.id.account_type);
mAccountNameTextView = (TextView) findViewById(R.id.account_name);
-
- mOrganizationView = mInflater.inflate(
- R.layout.organization_editor_view_switcher, mFields, false);
- mAddOrganizationButton = mOrganizationView.findViewById(
- R.id.add_organization_button);
- mOrganizationSectionViewContainer =
- (ViewGroup) mOrganizationView.findViewById(R.id.container);
-
- mAddFieldButton = (Button) findViewById(R.id.button_add_field);
- mAddFieldButton.setOnClickListener(new OnClickListener() {
- @Override
- public void onClick(View v) {
- showAddInformationPopupWindow();
- }
- });
}
@Override
protected Parcelable onSaveInstanceState() {
Bundle bundle = new Bundle();
- bundle.putBoolean(KEY_ORGANIZATION_VIEW_EXPANDED, mOrganizationViewExpanded);
// super implementation of onSaveInstanceState returns null
bundle.putParcelable(KEY_SUPER_INSTANCE_STATE, super.onSaveInstanceState());
return bundle;
@@ -178,20 +146,10 @@ public class RawContactEditorView extends BaseRawContactEditorView {
protected void onRestoreInstanceState(Parcelable state) {
if (state instanceof Bundle) {
Bundle bundle = (Bundle) state;
- mOrganizationViewExpanded = bundle.getBoolean(KEY_ORGANIZATION_VIEW_EXPANDED);
- if (mOrganizationViewExpanded) {
- // we have to manually perform the expansion here because
- // onRestoreInstanceState is called after setState. So at the point
- // of the creation of the organization view, mOrganizationViewExpanded
- // does not have the correct value yet.
- mOrganizationSectionViewContainer.setVisibility(VISIBLE);
- mAddOrganizationButton.setVisibility(GONE);
- }
super.onRestoreInstanceState(bundle.getParcelable(KEY_SUPER_INSTANCE_STATE));
return;
}
super.onRestoreInstanceState(state);
- return;
}
/**
@@ -213,9 +171,8 @@ public class RawContactEditorView extends BaseRawContactEditorView {
setId(vig.getId(state, null, null, ViewIdGenerator.NO_VIEW_INDEX));
- // Make sure we have a StructuredName and Organization
+ // Make sure we have a StructuredName
RawContactModifier.ensureKindExists(state, type, StructuredName.CONTENT_ITEM_TYPE);
- RawContactModifier.ensureKindExists(state, type, Organization.CONTENT_ITEM_TYPE);
mRawContactId = state.getRawContactId();
@@ -293,38 +250,14 @@ public class RawContactEditorView extends BaseRawContactEditorView {
} else if (GroupMembership.CONTENT_ITEM_TYPE.equals(mimeType)) {
if (mGroupMembershipView != null) {
mGroupMembershipView.setState(state);
+ mFields.addView(mGroupMembershipView);
}
- } else if (Organization.CONTENT_ITEM_TYPE.equals(mimeType)) {
- // Create the organization section
- final KindSectionView section = (KindSectionView) mInflater.inflate(
- R.layout.item_kind_section, mFields, false);
- section.setTitleVisible(false);
- section.setEnabled(isEnabled());
- section.setState(kind, state, false, vig);
-
- // If there is organization info for the contact already, display it
- if (!section.isEmpty()) {
- mFields.addView(section);
- } else {
- // Otherwise provide the user with an "add organization" button that shows the
- // EditText fields only when clicked
- mOrganizationSectionViewContainer.removeAllViews();
- mOrganizationSectionViewContainer.addView(section);
-
- // Setup the click listener for the "add organization" button
- mAddOrganizationButton.setOnClickListener(new OnClickListener() {
- @Override
- public void onClick(View v) {
- // Once the user expands the organization field, the user cannot
- // collapse them again.
- EditorAnimator.getInstance().expandOrganization(mAddOrganizationButton,
- mOrganizationSectionViewContainer);
- mOrganizationViewExpanded = true;
- }
- });
-
- mFields.addView(mOrganizationView);
- }
+ } else if (DataKind.PSEUDO_MIME_TYPE_DISPLAY_NAME.equals(mimeType)
+ || DataKind.PSEUDO_MIME_TYPE_PHONETIC_NAME.equals(mimeType)
+ || Nickname.CONTENT_ITEM_TYPE.equals(mimeType)) {
+ // Don't create fields for each of these mime-types. Instead, a single merged
+ // field is created for these mime-types.
+ continue;
} else {
// Otherwise use generic section-based editors
if (kind.fieldList == null) continue;
@@ -336,18 +269,7 @@ public class RawContactEditorView extends BaseRawContactEditorView {
}
}
- if (mGroupMembershipView != null) {
- mFields.addView(mGroupMembershipView);
- }
-
- updatePhoneticNameVisibility();
-
addToDefaultGroupIfNeeded();
-
-
- final int sectionCount = getSectionViewsWithoutFields().size();
- mAddFieldButton.setVisibility(sectionCount > 0 ? View.VISIBLE : View.GONE);
- mAddFieldButton.setEnabled(isEnabled());
}
@Override
@@ -431,89 +353,8 @@ public class RawContactEditorView extends BaseRawContactEditorView {
return mPhoneticName;
}
- private void updatePhoneticNameVisibility() {
- boolean showByDefault =
- getContext().getResources().getBoolean(R.bool.config_editor_include_phonetic_name);
-
- if (showByDefault || mPhoneticName.hasData() || mPhoneticNameAdded) {
- mPhoneticName.setVisibility(View.VISIBLE);
- } else {
- mPhoneticName.setVisibility(View.GONE);
- }
- }
-
@Override
public long getRawContactId() {
return mRawContactId;
}
-
- /**
- * Return a list of KindSectionViews that have no fields yet...
- * these are candidates to have fields added in
- * {@link #showAddInformationPopupWindow()}
- */
- private ArrayList<KindSectionView> getSectionViewsWithoutFields() {
- final ArrayList<KindSectionView> fields =
- new ArrayList<KindSectionView>(mFields.getChildCount());
- for (int i = 0; i < mFields.getChildCount(); i++) {
- View child = mFields.getChildAt(i);
- if (child instanceof KindSectionView) {
- final KindSectionView sectionView = (KindSectionView) child;
- // If the section is already visible (has 1 or more editors), then don't offer the
- // option to add this type of field in the popup menu
- if (sectionView.getEditorCount() > 0) {
- continue;
- }
- DataKind kind = sectionView.getKind();
- // not a list and already exists? ignore
- if ((kind.typeOverallMax == 1) && sectionView.getEditorCount() != 0) {
- continue;
- }
- if (DataKind.PSEUDO_MIME_TYPE_DISPLAY_NAME.equals(kind.mimeType)) {
- continue;
- }
-
- if (DataKind.PSEUDO_MIME_TYPE_PHONETIC_NAME.equals(kind.mimeType)
- && mPhoneticName.getVisibility() == View.VISIBLE) {
- continue;
- }
-
- fields.add(sectionView);
- }
- }
- return fields;
- }
-
- private void showAddInformationPopupWindow() {
- final ArrayList<KindSectionView> fields = getSectionViewsWithoutFields();
- final PopupMenu popupMenu = new PopupMenu(getContext(), mAddFieldButton);
- final Menu menu = popupMenu.getMenu();
- for (int i = 0; i < fields.size(); i++) {
- menu.add(Menu.NONE, i, Menu.NONE, fields.get(i).getTitle());
- }
-
- popupMenu.setOnMenuItemClickListener(new PopupMenu.OnMenuItemClickListener() {
- @Override
- public boolean onMenuItemClick(MenuItem item) {
- final KindSectionView view = fields.get(item.getItemId());
- if (DataKind.PSEUDO_MIME_TYPE_PHONETIC_NAME.equals(view.getKind().mimeType)) {
- mPhoneticNameAdded = true;
- updatePhoneticNameVisibility();
- mPhoneticName.requestFocus();
- } else {
- view.addItem();
- }
-
- // If this was the last section without an entry, we just added one, and therefore
- // there's no reason to show the button.
- if (fields.size() == 1) {
- mAddFieldButton.setVisibility(View.GONE);
- }
-
- return true;
- }
- });
-
- popupMenu.show();
- }
}
diff --git a/src/com/android/contacts/editor/TextFieldsEditorView.java b/src/com/android/contacts/editor/TextFieldsEditorView.java
index 841e2fa87..03e49fae4 100644
--- a/src/com/android/contacts/editor/TextFieldsEditorView.java
+++ b/src/com/android/contacts/editor/TextFieldsEditorView.java
@@ -26,7 +26,7 @@ import android.text.TextUtils;
import android.text.TextWatcher;
import android.util.AttributeSet;
import android.util.Log;
-import android.view.Gravity;
+import android.util.TypedValue;
import android.view.View;
import android.view.ViewGroup;
import android.view.inputmethod.EditorInfo;
@@ -58,9 +58,8 @@ public class TextFieldsEditorView extends LabeledEditorView {
private boolean mHideOptional = true;
private boolean mHasShortAndLongForms;
private int mMinFieldHeight;
- private int mEditTextTopPadding;
- private int mEditTextBottomPadding;
private int mPreviousViewHeight;
+ private int mHintTextColor;
public TextFieldsEditorView(Context context) {
super(context);
@@ -84,38 +83,37 @@ public class TextFieldsEditorView extends LabeledEditorView {
mMinFieldHeight = mContext.getResources().getDimensionPixelSize(
R.dimen.editor_min_line_item_height);
- mEditTextBottomPadding = mContext.getResources().getDimensionPixelSize(
- R.dimen.editor_text_field_bottom_padding);
- mEditTextTopPadding = mContext.getResources().getDimensionPixelSize(
- R.dimen.editor_text_field_top_padding);
mFields = (ViewGroup) findViewById(R.id.editors);
+ mHintTextColor = getResources().getColor(R.color.secondary_text_color);
mExpansionView = (ImageView) findViewById(R.id.expansion_view);
mExpansionViewContainer = findViewById(R.id.expansion_view_container);
- mExpansionViewContainer.setOnClickListener(new OnClickListener() {
- @Override
- public void onClick(View v) {
- mPreviousViewHeight = mFields.getHeight();
-
- // Save focus
- final View focusedChild = getFocusedChild();
- final int focusedViewId = focusedChild == null ? -1 : focusedChild.getId();
-
- // Reconfigure GUI
- mHideOptional = !mHideOptional;
- onOptionalFieldVisibilityChange();
- rebuildValues();
-
- // Restore focus
- View newFocusView = findViewById(focusedViewId);
- if (newFocusView == null || newFocusView.getVisibility() == GONE) {
- // find first visible child
- newFocusView = TextFieldsEditorView.this;
+ if (mExpansionViewContainer != null) {
+ mExpansionViewContainer.setOnClickListener(new OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ mPreviousViewHeight = mFields.getHeight();
+
+ // Save focus
+ final View focusedChild = getFocusedChild();
+ final int focusedViewId = focusedChild == null ? -1 : focusedChild.getId();
+
+ // Reconfigure GUI
+ mHideOptional = !mHideOptional;
+ onOptionalFieldVisibilityChange();
+ rebuildValues();
+
+ // Restore focus
+ View newFocusView = findViewById(focusedViewId);
+ if (newFocusView == null || newFocusView.getVisibility() == GONE) {
+ // find first visible child
+ newFocusView = TextFieldsEditorView.this;
+ }
+ newFocusView.requestFocus();
+
+ EditorAnimator.getInstance().slideAndFadeIn(mFields, mPreviousViewHeight);
}
- newFocusView.requestFocus();
-
- EditorAnimator.getInstance().slideAndFadeIn(mFields, mPreviousViewHeight);
- }
- });
+ });
+ }
}
@Override
@@ -143,7 +141,9 @@ public class TextFieldsEditorView extends LabeledEditorView {
mFieldEditTexts[index].setEnabled(!isReadOnly() && enabled);
}
}
- mExpansionView.setEnabled(!isReadOnly() && enabled);
+ if (mExpansionView != null) {
+ mExpansionView.setEnabled(!isReadOnly() && enabled);
+ }
}
/**
@@ -203,18 +203,9 @@ public class TextFieldsEditorView extends LabeledEditorView {
final EditText fieldView = new EditText(mContext);
fieldView.setLayoutParams(new LinearLayout.LayoutParams(LayoutParams.MATCH_PARENT,
LayoutParams.WRAP_CONTENT));
- // Set either a minimum line requirement or a minimum height (because {@link TextView}
- // only takes one or the other at a single time).
- if (field.minLines != 0) {
- fieldView.setMinLines(field.minLines);
- } else {
- fieldView.setMinHeight(mMinFieldHeight);
- }
- fieldView.setTextAppearance(getContext(), android.R.style.TextAppearance_Medium);
- fieldView.setPadding(fieldView.getPaddingLeft(), mEditTextTopPadding,
- fieldView.getPaddingRight(), mEditTextBottomPadding);
- fieldView.setHintTextColor(R.color.secondary_text_color);
- fieldView.setGravity(Gravity.TOP);
+ fieldView.setTextSize(TypedValue.COMPLEX_UNIT_PX,
+ getResources().getDimension(R.dimen.editor_form_text_size));
+ fieldView.setHintTextColor(mHintTextColor);
mFieldEditTexts[index] = fieldView;
fieldView.setId(vig.getId(state, kind, entry, index));
if (field.titleRes > 0) {
@@ -227,6 +218,16 @@ public class TextFieldsEditorView extends LabeledEditorView {
fieldView.setTextDirection(View.TEXT_DIRECTION_LTR);
}
+ // Set either a minimum line requirement or a minimum height (because {@link TextView}
+ // only takes one or the other at a single time).
+ if (field.minLines > 1) {
+ fieldView.setMinLines(field.minLines);
+ } else {
+ // This needs to be called after setInputType. Otherwise, calling setInputType
+ // will unset this value.
+ fieldView.setMinHeight(mMinFieldHeight);
+ }
+
// Show the "next" button in IME to navigate between text fields
// TODO: Still need to properly navigate to/from sections without text fields,
// See Bug: 5713510
@@ -278,10 +279,11 @@ public class TextFieldsEditorView extends LabeledEditorView {
mFields.addView(fieldView);
}
- // When hiding fields, place expandable
- setupExpansionView(hidePossible, mHideOptional);
- mExpansionView.setEnabled(!readOnly && isEnabled());
-
+ if (mExpansionView != null) {
+ // When hiding fields, place expandable
+ setupExpansionView(hidePossible, mHideOptional);
+ mExpansionView.setEnabled(!readOnly && isEnabled());
+ }
updateEmptiness();
}