Merge "Show popup for aggregation suggestion"
diff --git a/res/layout-sw580dp/aggregation_suggestions_item.xml b/res/layout-sw580dp/aggregation_suggestions_item.xml
deleted file mode 100644
index 5ea8347..0000000
--- a/res/layout-sw580dp/aggregation_suggestions_item.xml
+++ /dev/null
@@ -1,61 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-/*
- * Copyright 2010, 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.
- */
--->
-
-<view xmlns:android="http://schemas.android.com/apk/res/android"
- class="com.android.contacts.editor.AggregationSuggestionView"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:orientation="horizontal"
- android:paddingLeft="5dip"
- android:paddingRight="15dip"
- android:background="?android:attr/selectableItemBackground"
- android:focusable="true"
->
- <ImageView
- android:id="@+id/aggregation_suggestion_photo"
- android:layout_width="@dimen/aggregation_suggestion_icon_size"
- android:layout_height="@dimen/aggregation_suggestion_icon_size"
- android:layout_alignParentLeft="true"
- android:layout_centerInParent="true"
- android:layout_marginTop="4dip"
- android:scaleType="fitCenter"
- />
-
- <TextView
- android:id="@+id/aggregation_suggestion_name"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_toRightOf="@id/aggregation_suggestion_photo"
- android:layout_marginLeft="10dip"
- android:layout_marginTop="4dip"
- android:textAppearance="?android:attr/textAppearanceLarge"
- android:textColor="?android:attr/textColorSecondary"
- />
-
- <TextView
- android:id="@+id/aggregation_suggestion_data"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_toRightOf="@id/aggregation_suggestion_photo"
- android:layout_below="@id/aggregation_suggestion_name"
- android:layout_marginLeft="10dip"
- android:textAppearance="?android:attr/textAppearanceMedium"
- android:textColor="?android:attr/textColorSecondary"
- />
-</view>
diff --git a/res/layout/account_selector_list_item.xml b/res/layout/account_selector_list_item.xml
index 82b73da..a700866 100644
--- a/res/layout/account_selector_list_item.xml
+++ b/res/layout/account_selector_list_item.xml
@@ -22,7 +22,7 @@
android:layout_width="@dimen/detail_network_icon_size"
android:layout_height="@dimen/detail_network_icon_size"
android:layout_margin="8dip"
- android:layout_gravity="center_vertical"/>
+ android:layout_gravity="center_vertical" />
<LinearLayout
android:layout_width="0dip"
diff --git a/res/layout/aggregation_suggestions_item.xml b/res/layout/aggregation_suggestions_item.xml
index 9ed1bf3..188a26e 100644
--- a/res/layout/aggregation_suggestions_item.xml
+++ b/res/layout/aggregation_suggestions_item.xml
@@ -21,42 +21,34 @@
class="com.android.contacts.editor.AggregationSuggestionView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
- android:orientation="horizontal"
- android:paddingLeft="5dip"
- android:paddingRight="15dip"
+ android:minHeight="48dip"
+ android:paddingLeft="8dip"
android:background="?android:attr/selectableItemBackground"
- android:focusable="true"
->
+ android:orientation="horizontal">
+
+ <LinearLayout
+ android:layout_width="0px"
+ android:layout_height="wrap_content"
+ android:layout_weight="1"
+ android:orientation="vertical"
+ android:layout_gravity="center_vertical">
+ <TextView
+ android:id="@+id/aggregation_suggestion_name"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:textAppearance="?android:attr/textAppearanceMedium" />
+ <TextView
+ android:id="@+id/aggregation_suggestion_data"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:textAppearance="?android:attr/textAppearanceSmall"
+ android:textColor="?android:attr/textColorSecondary" />
+ </LinearLayout>
<ImageView
android:id="@+id/aggregation_suggestion_photo"
- android:layout_width="@dimen/aggregation_suggestion_icon_size"
- android:layout_height="@dimen/aggregation_suggestion_icon_size"
- android:layout_alignParentLeft="true"
- android:layout_centerInParent="true"
- android:layout_marginTop="4dip"
+ android:layout_width="48dip"
+ android:layout_height="48dip"
android:scaleType="fitCenter"
- />
-
- <TextView
- android:id="@+id/aggregation_suggestion_name"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_toRightOf="@id/aggregation_suggestion_photo"
- android:layout_marginLeft="10dip"
- android:layout_marginTop="4dip"
- android:textAppearance="?android:attr/textAppearanceSmall"
- android:textColor="?android:attr/textColorSecondary"
- />
-
- <TextView
- android:id="@+id/aggregation_suggestion_data"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_toRightOf="@id/aggregation_suggestion_photo"
- android:layout_below="@id/aggregation_suggestion_name"
- android:layout_marginLeft="10dip"
- android:textAppearance="?android:attr/textAppearanceSmall"
- android:textColor="?android:attr/textColorSecondary"
- />
+ android:layout_gravity="center_vertical" />
</view>
diff --git a/res/layout/edit_field_list.xml b/res/layout/edit_field_list.xml
index ba715c7..d46828b 100644
--- a/res/layout/edit_field_list.xml
+++ b/res/layout/edit_field_list.xml
@@ -23,4 +23,4 @@
android:layout_weight="1"
android:layout_height="wrap_content"
android:paddingLeft="@dimen/editor_field_left_padding"
- android:orientation="vertical" />
\ No newline at end of file
+ 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
new file mode 100644
index 0000000..fa69a5c
--- /dev/null
+++ b/res/layout/edit_field_list_with_anchor_view.xml
@@ -0,0 +1,35 @@
+<?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 that behaves similarly to edit_field_list.xml,
+ but also has an anchor view for ListPopupWindow -->
+<LinearLayout
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="0dip"
+ android:layout_height="wrap_content"
+ android:layout_weight="1"
+ android:paddingLeft="@dimen/editor_field_left_padding"
+ android:orientation="vertical">
+ <LinearLayout
+ android:id="@+id/editors"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:orientation="vertical" />
+ <View
+ android:id="@+id/anchor_view"
+ android:layout_width="match_parent"
+ android:layout_height="0px" />
+</LinearLayout>
diff --git a/res/layout/raw_contact_editor_view.xml b/res/layout/raw_contact_editor_view.xml
index b98f4fb..af95e04 100644
--- a/res/layout/raw_contact_editor_view.xml
+++ b/res/layout/raw_contact_editor_view.xml
@@ -66,13 +66,6 @@
</LinearLayout>
- <ViewStub android:id="@+id/aggregation_suggestion_stub"
- android:inflatedId="@+id/aggregation_suggestion"
- android:layout="@layout/aggregation_suggestions"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:visibility="visible"/>
-
<LinearLayout
android:id="@+id/sect_fields"
android:layout_width="match_parent"
diff --git a/res/layout/structured_name_editor_view.xml b/res/layout/structured_name_editor_view.xml
index 196b079..3c5d5c9 100644
--- a/res/layout/structured_name_editor_view.xml
+++ b/res/layout/structured_name_editor_view.xml
@@ -34,8 +34,7 @@
android:clickable="true">
<include
- android:id="@+id/editors"
- layout="@layout/edit_field_list" />
+ layout="@layout/edit_field_list_with_anchor_view" />
<include
android:id="@+id/expansion_view_container"
diff --git a/res/layout/text_fields_editor_view.xml b/res/layout/text_fields_editor_view.xml
index e63b7da..e187a9e 100644
--- a/res/layout/text_fields_editor_view.xml
+++ b/res/layout/text_fields_editor_view.xml
@@ -31,8 +31,7 @@
android:clickable="true">
<include
- android:id="@+id/editors"
- layout="@layout/edit_field_list" />
+ layout="@layout/edit_field_list_with_anchor_view" />
<include
android:id="@+id/expansion_view_container"
diff --git a/res/values-sw580dp/dimens.xml b/res/values-sw580dp/dimens.xml
index f7c0f05..91842d6 100644
--- a/res/values-sw580dp/dimens.xml
+++ b/res/values-sw580dp/dimens.xml
@@ -14,7 +14,6 @@
limitations under the License.
-->
<resources>
- <dimen name="aggregation_suggestion_icon_size">64dip</dimen>
<dimen name="editor_padding_top">32dip</dimen>
<dimen name="editor_type_label_width">122dip</dimen>
<dimen name="editor_field_spinner_text_size">15sp</dimen>
diff --git a/res/values/dimens.xml b/res/values/dimens.xml
index d5f3b69..1edc590 100644
--- a/res/values/dimens.xml
+++ b/res/values/dimens.xml
@@ -21,8 +21,6 @@
<dimen name="contact_shortcut_frame_width">50dip</dimen>
<dimen name="contact_shortcut_frame_height">56dip</dimen>
- <dimen name="aggregation_suggestion_icon_size">40dip</dimen>
-
<dimen name="account_selector_popup_width">400dip</dimen>
<dimen name="photo_action_popup_width">400dip</dimen>
@@ -249,4 +247,5 @@
<!-- Height for directory headers in contact lists -->
<dimen name="directory_header_height">24dip</dimen>
+
</resources>
diff --git a/src/com/android/contacts/editor/AggregationSuggestionView.java b/src/com/android/contacts/editor/AggregationSuggestionView.java
index 07e67e8..df90cff 100644
--- a/src/com/android/contacts/editor/AggregationSuggestionView.java
+++ b/src/com/android/contacts/editor/AggregationSuggestionView.java
@@ -29,7 +29,7 @@
import android.provider.ContactsContract.Contacts;
import android.util.AttributeSet;
import android.widget.ImageView;
-import android.widget.RelativeLayout;
+import android.widget.LinearLayout;
import android.widget.TextView;
import java.util.ArrayList;
@@ -38,7 +38,7 @@
/**
* A view that contains a name, picture and other data for a contact aggregation suggestion.
*/
-public class AggregationSuggestionView extends RelativeLayout {
+public class AggregationSuggestionView extends LinearLayout {
public interface Listener {
@@ -63,17 +63,14 @@
public AggregationSuggestionView(Context context) {
super(context);
- setClickable(true);
}
public AggregationSuggestionView(Context context, AttributeSet attrs) {
super(context, attrs);
- setClickable(true);
}
public AggregationSuggestionView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
- setClickable(true);
}
public void setNewContact(boolean flag) {
@@ -135,8 +132,7 @@
mListener = listener;
}
- @Override
- public boolean performClick() {
+ public boolean handleItemClickEvent() {
if (mListener != null && isEnabled()) {
if (canEditSuggestedContact()) {
mListener.onEditAction(Contacts.getLookupUri(mContactId, mLookupKey));
diff --git a/src/com/android/contacts/editor/ContactEditorFragment.java b/src/com/android/contacts/editor/ContactEditorFragment.java
index 412efab..afc3ab1 100644
--- a/src/com/android/contacts/editor/ContactEditorFragment.java
+++ b/src/com/android/contacts/editor/ContactEditorFragment.java
@@ -83,6 +83,8 @@
import android.view.ViewGroup.MarginLayoutParams;
import android.view.ViewStub;
import android.widget.AdapterView;
+import android.widget.AdapterView.OnItemClickListener;
+import android.widget.BaseAdapter;
import android.widget.LinearLayout;
import android.widget.ListPopupWindow;
import android.widget.Toast;
@@ -207,17 +209,6 @@
private Cursor mGroupMetaData;
- /**
- * A delay in milliseconds used for bringing aggregation suggestions to
- * the visible part of the screen. The reason this has to be done after
- * a delay is a race condition with the soft keyboard. The keyboard
- * may expand to display its own autocomplete suggestions, which will
- * reduce the visible area of the screen. We will yield to the keyboard
- * hoping that the delay is sufficient. If not - part of the
- * suggestion will be hidden, which is not fatal.
- */
- private static final int AGGREGATION_SUGGESTION_SCROLL_DELAY = 200;
-
private File mCurrentPhotoFile;
// Height/width (in pixels) to request for the photo - queried from the provider.
@@ -245,6 +236,62 @@
private long mAggregationSuggestionsRawContactId;
private View mAggregationSuggestionView;
+ private ListPopupWindow mAggregationSuggestionPopup;
+
+ private static final class AggregationSuggestionAdapter extends BaseAdapter {
+ private final Activity mActivity;
+ private final boolean mSetNewContact;
+ private final AggregationSuggestionView.Listener mListener;
+ private final List<Suggestion> mSuggestions;
+
+ public AggregationSuggestionAdapter(Activity activity, boolean setNewContact,
+ AggregationSuggestionView.Listener listener, List<Suggestion> suggestions) {
+ mActivity = activity;
+ mSetNewContact = setNewContact;
+ mListener = listener;
+ mSuggestions = suggestions;
+ }
+
+ @Override
+ public View getView(int position, View convertView, ViewGroup parent) {
+ Suggestion suggestion = (Suggestion) getItem(position);
+ LayoutInflater inflater = mActivity.getLayoutInflater();
+ AggregationSuggestionView suggestionView =
+ (AggregationSuggestionView) inflater.inflate(
+ R.layout.aggregation_suggestions_item, null);
+ suggestionView.setNewContact(mSetNewContact);
+ suggestionView.setListener(mListener);
+ suggestionView.bindSuggestion(suggestion);
+ return suggestionView;
+ }
+
+ @Override
+ public long getItemId(int position) {
+ return position;
+ }
+
+ @Override
+ public Object getItem(int position) {
+ return mSuggestions.get(position);
+ }
+
+ @Override
+ public int getCount() {
+ return mSuggestions.size();
+ }
+ }
+
+ private OnItemClickListener mAggregationSuggestionItemClickListener =
+ new OnItemClickListener() {
+ @Override
+ public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
+ final AggregationSuggestionView suggestionView = (AggregationSuggestionView) view;
+ suggestionView.handleItemClickEvent();
+ mAggregationSuggestionPopup.dismiss();
+ mAggregationSuggestionPopup = null;
+ }
+ };
+
private boolean mAutoAddToDefaultGroup;
private boolean mEnabled = true;
@@ -1276,76 +1323,28 @@
return;
}
- RawContactEditorView rawContactView =
+ if (mAggregationSuggestionPopup != null && mAggregationSuggestionPopup.isShowing()) {
+ mAggregationSuggestionPopup.dismiss();
+ }
+
+ if (mAggregationSuggestionEngine.getSuggestedContactCount() == 0) {
+ return;
+ }
+
+ final RawContactEditorView rawContactView =
(RawContactEditorView)getRawContactEditorView(mAggregationSuggestionsRawContactId);
- if (rawContactView == null) {
- return;
- }
-
- ViewStub stub = (ViewStub)rawContactView.findViewById(R.id.aggregation_suggestion_stub);
- if (stub != null) {
- stub.inflate();
- }
-
- // Only request the view on screen when it is first displayed
- boolean requestOnScreen = mAggregationSuggestionView == null;
- mAggregationSuggestionView = rawContactView.findViewById(R.id.aggregation_suggestion);
-
- int count = mAggregationSuggestionEngine.getSuggestedContactCount();
- if (count == 0) {
- mAggregationSuggestionView.setVisibility(View.GONE);
- return;
- }
-
- List<Suggestion> suggestions = mAggregationSuggestionEngine.getSuggestions();
-
- LinearLayout itemList = (LinearLayout) mAggregationSuggestionView.findViewById(
- R.id.aggregation_suggestions);
- itemList.removeAllViews();
-
- LayoutInflater inflater = getActivity().getLayoutInflater();
-
- for (Suggestion suggestion : suggestions) {
- AggregationSuggestionView suggestionView =
- (AggregationSuggestionView) inflater.inflate(
- R.layout.aggregation_suggestions_item, null);
- suggestionView.setLayoutParams(
- new LinearLayout.LayoutParams(
- LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT));
- suggestionView.setNewContact(mState.size() == 1 && mState.get(0).isContactInsert());
- suggestionView.setListener(this);
- suggestionView.bindSuggestion(suggestion);
- itemList.addView(suggestionView);
- }
-
- adjustAggregationSuggestionViewLayout(rawContactView);
- setAggregationSuggestionViewEnabled(mEnabled);
- mAggregationSuggestionView.setVisibility(View.VISIBLE);
-
- if (requestOnScreen) {
- mContent.postDelayed(new Runnable() {
-
- @Override
- public void run() {
- requestAggregationSuggestionOnScreen(mAggregationSuggestionView);
- }
- }, AGGREGATION_SUGGESTION_SCROLL_DELAY);
- }
- }
-
- /**
- * Adjusts the layout of the aggregation suggestion view so that it is placed directly
- * underneath and have the same width as the last text editor of the contact name editor.
- */
- private void adjustAggregationSuggestionViewLayout(RawContactEditorView rawContactView) {
- TextFieldsEditorView nameEditor = rawContactView.getNameEditor();
- Rect rect = new Rect();
- nameEditor.acquireEditorBounds(rect);
- MarginLayoutParams layoutParams =
- (MarginLayoutParams) mAggregationSuggestionView.getLayoutParams();
- layoutParams.leftMargin = rect.left;
- layoutParams.width = rect.width();
- mAggregationSuggestionView.setLayoutParams(layoutParams);
+ final View anchorView = rawContactView.findViewById(R.id.anchor_view);
+ mAggregationSuggestionPopup = new ListPopupWindow(mContext, null);
+ mAggregationSuggestionPopup.setAnchorView(anchorView);
+ mAggregationSuggestionPopup.setWidth(anchorView.getWidth());
+ mAggregationSuggestionPopup.setInputMethodMode(ListPopupWindow.INPUT_METHOD_NOT_NEEDED);
+ mAggregationSuggestionPopup.setModal(true);
+ mAggregationSuggestionPopup.setAdapter(
+ new AggregationSuggestionAdapter(getActivity(),
+ mState.size() == 1 && mState.get(0).isContactInsert(),
+ this, mAggregationSuggestionEngine.getSuggestions()));
+ mAggregationSuggestionPopup.setOnItemClickListener(mAggregationSuggestionItemClickListener);
+ mAggregationSuggestionPopup.show();
}
@Override
@@ -1452,20 +1451,6 @@
}
}
- /**
- * Scrolls the editor if necessary to reveal the aggregation suggestion that is
- * shown below the name editor. Makes sure that the currently focused field
- * remains visible.
- */
- private void requestAggregationSuggestionOnScreen(final View view) {
- Rect rect = getRelativeBounds(mContent, view);
- View focused = mContent.findFocus();
- if (focused != null) {
- rect.union(getRelativeBounds(mContent, focused));
- }
- mContent.requestRectangleOnScreen(rect);
- }
-
public void setAggregationSuggestionViewEnabled(boolean enabled) {
if (mAggregationSuggestionView == null) {
return;