From 73b51d5771b31c932a589abc9bb0fe64c52fe102 Mon Sep 17 00:00:00 2001 From: calderwoodra Date: Fri, 8 Dec 2017 20:52:56 -0800 Subject: Implemented adding a new favorites contact flow NUI. This change consists of mainly 3 things: - Update contacts fragment to meet AddFavoriteActivity requirements - Implement AddFavoriteActivity - Passing the contact back to SpeedDialFragment Bug: 36841782 Test: SpeedDialIntegrationTest PiperOrigin-RevId: 178461265 Change-Id: Ib3a13eae311acf6ce10a94df4f2c95b9af120cff --- .../dialer/contactsfragment/ContactViewHolder.java | 31 ++---- .../dialer/contactsfragment/ContactsAdapter.java | 20 ++-- .../contactsfragment/ContactsCursorLoader.java | 57 +++++++--- .../dialer/contactsfragment/ContactsFragment.java | 120 ++++++++++++--------- 4 files changed, 136 insertions(+), 92 deletions(-) (limited to 'java/com/android/dialer/contactsfragment') diff --git a/java/com/android/dialer/contactsfragment/ContactViewHolder.java b/java/com/android/dialer/contactsfragment/ContactViewHolder.java index 0597c2a7e..2730c0d38 100644 --- a/java/com/android/dialer/contactsfragment/ContactViewHolder.java +++ b/java/com/android/dialer/contactsfragment/ContactViewHolder.java @@ -18,7 +18,6 @@ package com.android.dialer.contactsfragment; import android.content.Context; import android.net.Uri; -import android.provider.ContactsContract.QuickContact; import android.support.v7.widget.RecyclerView; import android.text.TextUtils; import android.view.View; @@ -26,7 +25,7 @@ import android.view.View.OnClickListener; import android.widget.QuickContactBadge; import android.widget.TextView; import com.android.dialer.common.Assert; -import com.android.dialer.contactsfragment.ContactsFragment.ClickAction; +import com.android.dialer.contactsfragment.ContactsFragment.OnContactSelectedListener; import com.android.dialer.logging.InteractionEvent; import com.android.dialer.logging.Logger; @@ -37,20 +36,20 @@ final class ContactViewHolder extends RecyclerView.ViewHolder implements OnClick private final TextView name; private final QuickContactBadge photo; private final Context context; - private final @ClickAction int clickAction; + private final OnContactSelectedListener onContactSelectedListener; private String headerText; private Uri contactUri; + private long contactId; - ContactViewHolder(View itemView, @ClickAction int clickAction) { + ContactViewHolder(View itemView, OnContactSelectedListener onContactSelectedListener) { super(itemView); - Assert.checkArgument(clickAction != ClickAction.INVALID, "Invalid click action."); + this.onContactSelectedListener = Assert.isNotNull(onContactSelectedListener); context = itemView.getContext(); itemView.findViewById(R.id.click_target).setOnClickListener(this); header = itemView.findViewById(R.id.header); name = itemView.findViewById(R.id.contact_name); photo = itemView.findViewById(R.id.photo); - this.clickAction = clickAction; } /** @@ -61,9 +60,11 @@ final class ContactViewHolder extends RecyclerView.ViewHolder implements OnClick * @param contactUri to be shown by the contact card on photo click. * @param showHeader if header view should be shown {@code True}, {@code False} otherwise. */ - public void bind(String headerText, String displayName, Uri contactUri, boolean showHeader) { + public void bind( + String headerText, String displayName, Uri contactUri, long contactId, boolean showHeader) { Assert.checkArgument(!TextUtils.isEmpty(displayName)); this.contactUri = contactUri; + this.contactId = contactId; this.headerText = headerText; name.setText(displayName); @@ -89,20 +90,6 @@ final class ContactViewHolder extends RecyclerView.ViewHolder implements OnClick @Override public void onClick(View v) { - switch (clickAction) { - case ClickAction.OPEN_CONTACT_CARD: - Logger.get(context) - .logInteraction(InteractionEvent.Type.OPEN_QUICK_CONTACT_FROM_CONTACTS_FRAGMENT_ITEM); - QuickContact.showQuickContact( - photo.getContext(), - photo, - contactUri, - QuickContact.MODE_LARGE, - null /* excludeMimes */); - break; - case ClickAction.INVALID: - default: - throw Assert.createIllegalStateFailException("Invalid click action."); - } + onContactSelectedListener.onContactSelected(photo, contactUri, contactId); } } diff --git a/java/com/android/dialer/contactsfragment/ContactsAdapter.java b/java/com/android/dialer/contactsfragment/ContactsAdapter.java index 8f2120cd7..44abe29da 100644 --- a/java/com/android/dialer/contactsfragment/ContactsAdapter.java +++ b/java/com/android/dialer/contactsfragment/ContactsAdapter.java @@ -29,8 +29,8 @@ import android.view.ViewGroup; import com.android.dialer.common.Assert; import com.android.dialer.common.LogUtil; import com.android.dialer.contactphoto.ContactPhotoManager; -import com.android.dialer.contactsfragment.ContactsFragment.ClickAction; import com.android.dialer.contactsfragment.ContactsFragment.Header; +import com.android.dialer.contactsfragment.ContactsFragment.OnContactSelectedListener; import com.android.dialer.lettertile.LetterTileDrawable; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; @@ -50,7 +50,7 @@ final class ContactsAdapter extends RecyclerView.Adapter holderMap = new ArrayMap<>(); private final Context context; private final @Header int header; - private final @ClickAction int clickAction; + private final OnContactSelectedListener onContactSelectedListener; // List of contact sublist headers private String[] headers = new String[0]; @@ -59,10 +59,11 @@ final class ContactsAdapter extends RecyclerView.Adapter *
  • {@link Header#ADD_CONTACT} to insert a header that allows users to add a contact - *
  • {@link ClickAction#OPEN_CONTACT_CARD} to open contact cards on click + *
  • Open contact cards on click * * * And for the add favorite contact screen we might use: * *
      *
    • {@link Header#NONE} so that all rows are contacts (i.e. no header inserted) - *
    • {@link ClickAction#SET_RESULT_AND_FINISH} to send a selected contact to the previous - * activity. + *
    • Send a selected contact to the parent activity. *
    * * @param header determines the type of header inserted at position 0 in the contacts list - * @param clickAction defines the on click actions on rows that represent contacts */ - public static ContactsFragment newInstance(@Header int header, @ClickAction int clickAction) { - Assert.checkArgument(clickAction != ClickAction.INVALID, "Invalid click action"); + public static ContactsFragment newInstance(@Header int header) { ContactsFragment fragment = new ContactsFragment(); Bundle args = new Bundle(); args.putInt(EXTRA_HEADER, header); - args.putInt(EXTRA_CLICK_ACTION, clickAction); + fragment.setArguments(args); + return fragment; + } + + /** + * Returns {@link ContactsFragment} with a list of contacts such that: + * + *
      + *
    • Each contact has a phone number + *
    • Contacts are filterable via {@link #updateQuery(String)} + *
    • There is no list header (i.e. {@link Header#NONE} + *
    • Clicking on a contact notifies the parent activity via {@link + * OnContactSelectedListener#onContactSelected(ImageView, Uri, long)}. + *
    + */ + public static ContactsFragment newAddFavoritesInstance() { + ContactsFragment fragment = new ContactsFragment(); + Bundle args = new Bundle(); + args.putInt(EXTRA_HEADER, Header.NONE); + args.putBoolean(EXTRA_HAS_PHONE_NUMBERS, true); fragment.setArguments(args); return fragment; } @@ -152,7 +158,21 @@ public class ContactsFragment extends Fragment contactsPrefs = new ContactsPreferences(getContext()); contactsPrefs.registerChangeListener(this); header = getArguments().getInt(EXTRA_HEADER); - clickAction = getArguments().getInt(EXTRA_CLICK_ACTION); + hasPhoneNumbers = getArguments().getBoolean(EXTRA_HAS_PHONE_NUMBERS); + } + + @Override + public void onStart() { + super.onStart(); + PermissionsUtil.registerPermissionReceiver( + getActivity(), readContactsPermissionGrantedReceiver, READ_CONTACTS); + } + + @Override + public void onStop() { + PermissionsUtil.unregisterPermissionReceiver( + getActivity(), readContactsPermissionGrantedReceiver); + super.onStop(); } @Nullable @@ -163,7 +183,9 @@ public class ContactsFragment extends Fragment fastScroller = view.findViewById(R.id.fast_scroller); anchoredHeader = view.findViewById(R.id.header); recyclerView = view.findViewById(R.id.recycler_view); - adapter = new ContactsAdapter(getContext(), header, clickAction); + adapter = + new ContactsAdapter( + getContext(), header, FragmentUtils.getParent(this, OnContactSelectedListener.class)); recyclerView.setAdapter(adapter); manager = new LinearLayoutManager(getContext()) { @@ -208,15 +230,14 @@ public class ContactsFragment extends Fragment /** @return a loader according to sort order and display order. */ @Override public Loader onCreateLoader(int id, Bundle args) { - boolean sortOrderPrimary = - (contactsPrefs.getSortOrder() == ContactsPreferences.SORT_ORDER_PRIMARY); - boolean displayOrderPrimary = - (contactsPrefs.getDisplayOrder() == ContactsPreferences.DISPLAY_ORDER_PRIMARY); - - String sortKey = sortOrderPrimary ? Contacts.SORT_KEY_PRIMARY : Contacts.SORT_KEY_ALTERNATIVE; - return displayOrderPrimary - ? ContactsCursorLoader.createInstanceDisplayNamePrimary(getContext(), sortKey) - : ContactsCursorLoader.createInstanceDisplayNameAlternative(getContext(), sortKey); + ContactsCursorLoader cursorLoader = new ContactsCursorLoader(getContext(), hasPhoneNumbers); + cursorLoader.setQuery(query); + return cursorLoader; + } + + public void updateQuery(String query) { + this.query = query; + getLoaderManager().restartLoader(0, null, this); } @Override @@ -266,10 +287,13 @@ public class ContactsFragment extends Fragment } String anchoredHeaderString = adapter.getHeaderString(firstCompletelyVisible); - FragmentUtils.getParentUnsafe(this, OnContactsListScrolledListener.class) - .onContactsListScrolled( - recyclerView.getScrollState() == RecyclerView.SCROLL_STATE_DRAGGING - || fastScroller.isDragStarted()); + OnContactsListScrolledListener listener = + FragmentUtils.getParent(this, OnContactsListScrolledListener.class); + if (listener != null) { + listener.onContactsListScrolled( + recyclerView.getScrollState() == RecyclerView.SCROLL_STATE_DRAGGING + || fastScroller.isDragStarted()); + } // If the user swipes to the top of the list very quickly, there is some strange behavior // between this method updating headers and adapter#onBindViewHolder updating headers. @@ -331,17 +355,15 @@ public class ContactsFragment extends Fragment } } - @Override - public void onStart() { - super.onStart(); - PermissionsUtil.registerPermissionReceiver( - getActivity(), readContactsPermissionGrantedReceiver, READ_CONTACTS); + /** Listener for contacts list scroll state. */ + public interface OnContactsListScrolledListener { + void onContactsListScrolled(boolean isDragging); } - @Override - public void onStop() { - PermissionsUtil.unregisterPermissionReceiver( - getActivity(), readContactsPermissionGrantedReceiver); - super.onStop(); + /** Listener to notify parents when a contact is selected. */ + public interface OnContactSelectedListener { + + /** Called when a contact is selected in {@link ContactsFragment}. */ + void onContactSelected(ImageView photo, Uri contactUri, long contactId); } } -- cgit v1.2.3