diff options
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(); } |