Sort group editor autocomplete suggestions alphabetically

- Make drop down suggestions use a similar layout to the email
autocomplete dropdown layout (UX request). This also allows us
to view more suggestions on screen at a time.

Bug: 5197573
Change-Id: I96c3d8b93defb716c6df2530bdaa20e86275f564
diff --git a/res/layout/group_member_suggestion.xml b/res/layout/group_member_suggestion.xml
index 2cecf87..c6c3877 100644
--- a/res/layout/group_member_suggestion.xml
+++ b/res/layout/group_member_suggestion.xml
@@ -20,37 +20,43 @@
 <LinearLayout
     xmlns:android="http://schemas.android.com/apk/res/android"
     android:layout_width="match_parent"
-    android:layout_height="wrap_content"
+    android:layout_height="48dip"
     android:orientation="horizontal"
-    android:padding="10dip" >
+    android:gravity="center_vertical"
+    android:background="?android:attr/selectableItemBackground">
+
+    <LinearLayout
+        android:layout_width="0dip"
+        android:layout_height="match_parent"
+        android:layout_weight="1"
+        android:gravity="center_vertical"
+        android:orientation="vertical">
+
+        <TextView
+            android:id="@+id/text1"
+            android:textAppearance="?android:attr/textAppearanceMedium"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:paddingLeft="8dip"
+            android:singleLine="true"
+            android:ellipsize="end"/>
+
+        <TextView android:id="@+id/text2"
+            android:textAppearance="?android:attr/textAppearanceSmall"
+            android:textColor="?android:attr/textColorSecondary"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:paddingLeft="8dip"
+            android:singleLine="true"
+            android:ellipsize="end" />
+
+    </LinearLayout>
 
     <ImageView
         android:id="@+id/icon"
         android:layout_width="48dip"
         android:layout_height="48dip"
-        android:scaleType="centerInside"
-        android:layout_gravity="center" />
+        android:cropToPadding="true"
+        android:scaleType="centerCrop" />
 
-    <LinearLayout
-        android:layout_width="match_parent"
-        android:layout_height="wrap_content"
-        android:orientation="vertical"
-        android:paddingLeft="10dip" >
-
-        <TextView
-            android:id="@+id/text1"
-            android:textAppearance="?android:attr/textAppearanceMedium"
-            android:singleLine="true"
-            android:layout_width="match_parent"
-            android:layout_height="wrap_content" />
-
-        <TextView
-            android:id="@+id/text2"
-            android:textAppearance="?android:attr/textAppearanceSmall"
-            android:singleLine="true"
-            android:layout_width="match_parent"
-            android:layout_height="wrap_content" />
-
-    </LinearLayout>
-
-</LinearLayout>
+</LinearLayout>
\ No newline at end of file
diff --git a/src/com/android/contacts/group/SuggestedMemberListAdapter.java b/src/com/android/contacts/group/SuggestedMemberListAdapter.java
index bc8055a..623b5a2 100644
--- a/src/com/android/contacts/group/SuggestedMemberListAdapter.java
+++ b/src/com/android/contacts/group/SuggestedMemberListAdapter.java
@@ -173,7 +173,11 @@
                 return results;
             }
 
-            // Map of raw contact IDs to {@link SuggestedMember} objects
+            // Create a list to store the suggested contacts (which will be alphabetically ordered),
+            // but also keep a map of raw contact IDs to {@link SuggestedMember}s to make it easier
+            // to add supplementary data to the contact (photo, phone, email) to the members based
+            // on raw contact IDs after the second query is completed.
+            List<SuggestedMember> suggestionsList = new ArrayList<SuggestedMember>();
             HashMap<Long, SuggestedMember> suggestionsMap = new HashMap<Long, SuggestedMember>();
 
             // First query for all the raw contacts that match the given search query
@@ -197,7 +201,7 @@
                     accountClause + " AND (" +
                     RawContacts.DISPLAY_NAME_PRIMARY + " LIKE ? OR " +
                     RawContacts.DISPLAY_NAME_ALTERNATIVE + " LIKE ? )",
-                    args, null);
+                    args, RawContacts.DISPLAY_NAME_PRIMARY + " COLLATE LOCALIZED ASC");
 
             if (cursor == null) {
                 return results;
@@ -216,8 +220,11 @@
                     }
                     // Otherwise, add the contact as a suggested new group member
                     String displayName = cursor.getString(DISPLAY_NAME_PRIMARY_COLUMN_INDEX);
-                    suggestionsMap.put(rawContactId, new SuggestedMember(rawContactId,
-                            displayName, contactId));
+                    SuggestedMember member = new SuggestedMember(rawContactId, displayName,
+                            contactId);
+                    // Store the member in the list of suggestions and add it to the hash map too.
+                    suggestionsList.add(member);
+                    suggestionsMap.put(rawContactId, member);
                 }
             } finally {
                 cursor.close();
@@ -282,14 +289,14 @@
             } finally {
                 memberDataCursor.close();
             }
-            results.values = suggestionsMap;
+            results.values = suggestionsList;
             return results;
         }
 
         @Override
         protected void publishResults(CharSequence constraint, FilterResults results) {
-            HashMap<Long, SuggestedMember> map = (HashMap<Long, SuggestedMember>) results.values;
-            if (map == null || map.keySet() == null) {
+            List<SuggestedMember> suggestionsList = (List<SuggestedMember>) results.values;
+            if (suggestionsList == null) {
                 return;
             }
 
@@ -297,7 +304,7 @@
             clear();
 
             // Add all the suggested members to this adapter
-            for (SuggestedMember member : map.values()) {
+            for (SuggestedMember member : suggestionsList) {
                 add(member);
             }