Loading res/layout/call_log_fragment.xml +3 −10 Original line number Diff line number Diff line Loading @@ -61,18 +61,11 @@ <FrameLayout android:layout_width="match_parent" android:layout_height="match_parent"> <!-- clipChildren=false is required to ensure shadows drawn within list items aren't clipped by the list item bounds. --> <ListView android:id="@android:id/list" <android.support.v7.widget.RecyclerView android:id="@+id/recycler_view" android:layout_width="match_parent" android:layout_height="match_parent" android:fadingEdge="none" android:scrollbarStyle="outsideOverlay" android:background="@color/background_dialer_list_items" android:divider="@null" android:nestedScrollingEnabled="true" android:clipChildren="false" /> android:background="@color/background_dialer_list_items" /> <include android:id="@+id/empty_list_view" Loading src/com/android/dialer/calllog/CallLogAdapter.java +16 −40 Original line number Diff line number Diff line Loading @@ -23,6 +23,7 @@ import android.database.Cursor; import android.net.Uri; import android.provider.ContactsContract.CommonDataKinds.Phone; import android.provider.ContactsContract.PhoneLookup; import android.support.v7.widget.RecyclerView.ViewHolder; import android.telecom.PhoneAccountHandle; import android.telephony.PhoneNumberUtils; import android.text.TextUtils; Loading Loading @@ -225,13 +226,12 @@ public class CallLogAdapter extends GroupingListAdapter mLoading = loading; } @Override public boolean isEmpty() { if (mLoading) { // We don't want the empty state to show when loading. return false; } else { return super.isEmpty(); return getItemCount() == 0; } } Loading Loading @@ -262,48 +262,19 @@ public class CallLogAdapter extends GroupingListAdapter } @Override protected View newStandAloneView(Context context, ViewGroup parent) { return newChildView(context, parent); } @Override protected View newGroupView(Context context, ViewGroup parent) { return newChildView(context, parent); } @Override protected View newChildView(Context context, ViewGroup parent) { LayoutInflater inflater = LayoutInflater.from(context); public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { LayoutInflater inflater = LayoutInflater.from(mContext); View view = inflater.inflate(R.layout.call_log_list_item, parent, false); // Get the views to bind to and cache them. CallLogListItemViews views = CallLogListItemViews.fromView(context, view); CallLogListItemViews views = CallLogListItemViews.fromView(mContext, view); view.setTag(views); // Set text height to false on the TextViews so they don't have extra padding. views.phoneCallDetailsViews.nameView.setElegantTextHeight(false); views.phoneCallDetailsViews.callLocationAndDate.setElegantTextHeight(false); return view; } @Override protected void bindStandAloneView(View view, Context context, Cursor cursor) { bindView(view, cursor, 1); } @Override protected void bindChildView(View view, Context context, Cursor cursor) { bindView(view, cursor, 1); } @Override protected void bindGroupView(View view, Context context, Cursor cursor, int groupSize, boolean expanded) { bindView(view, cursor, groupSize); } private void findAndCacheViews(View view) { return (CallLogListItemViews) view.getTag(); } /** Loading @@ -312,12 +283,17 @@ public class CallLogAdapter extends GroupingListAdapter * should not. It invokes cross-process methods and the repeat execution can get costly. * * @param callLogItemView the view corresponding to this entry * @param c the cursor pointing to the entry in the call log * @param count the number of entries in the current item, greater than 1 if it is a group */ public void bindView(View callLogItemView, Cursor c, int count) { callLogItemView.setAccessibilityDelegate(mAccessibilityDelegate); final CallLogListItemViews views = (CallLogListItemViews) callLogItemView.getTag(); public void onBindViewHolder(ViewHolder viewHolder, int position) { Cursor c = (Cursor) getItem(position); if (c == null) { return; } int count = getGroupSize(position); CallLogListItemViews views = (CallLogListItemViews) viewHolder; views.rootView.setAccessibilityDelegate(mAccessibilityDelegate); // Default case: an item in the call log. views.primaryActionView.setVisibility(View.VISIBLE); Loading Loading @@ -435,7 +411,7 @@ public class CallLogAdapter extends GroupingListAdapter // Listen for the first draw if (mViewTreeObserver == null) { mViewTreeObserver = callLogItemView.getViewTreeObserver(); mViewTreeObserver = views.rootView.getViewTreeObserver(); mViewTreeObserver.addOnPreDrawListener(this); } } Loading src/com/android/dialer/calllog/CallLogFragment.java +22 −12 Original line number Diff line number Diff line Loading @@ -21,8 +21,8 @@ import android.animation.AnimatorListenerAdapter; import android.animation.ValueAnimator; import android.app.Activity; import android.app.DialogFragment; import android.app.Fragment; import android.app.KeyguardManager; import android.app.ListFragment; import android.content.Context; import android.content.Intent; import android.database.ContentObserver; Loading @@ -34,10 +34,11 @@ import android.provider.CallLog; import android.provider.CallLog.Calls; import android.provider.ContactsContract; import android.provider.VoicemailContract.Status; import android.support.v7.widget.RecyclerView; import android.support.v7.widget.LinearLayoutManager; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.view.ViewTreeObserver; import android.view.View.OnClickListener; import android.view.ViewGroup.LayoutParams; import android.widget.ListView; Loading @@ -60,7 +61,7 @@ import java.util.List; * Displays a list of call log entries. To filter for a particular kind of call * (all, missed or voicemails), specify it in the constructor. */ public class CallLogFragment extends ListFragment public class CallLogFragment extends Fragment implements CallLogQueryHandler.Listener, CallLogAdapter.OnReportButtonClickListener, CallLogAdapter.CallFetcher { private static final String TAG = "CallLogFragment"; Loading @@ -76,6 +77,8 @@ public class CallLogFragment extends ListFragment private static final String KEY_LOG_LIMIT = "log_limit"; private static final String KEY_DATE_LIMIT = "date_limit"; private RecyclerView mRecyclerView; private LinearLayoutManager mLayoutManager; private CallLogAdapter mAdapter; private CallLogQueryHandler mCallLogQueryHandler; private boolean mScrollToTop; Loading Loading @@ -172,9 +175,6 @@ public class CallLogFragment extends ListFragment } String currentCountryIso = GeoUtil.getCurrentCountryIso(getActivity()); mAdapter = ObjectFactory.newCallLogAdapter(getActivity(), this, new ContactInfoHelper(getActivity(), currentCountryIso), this); setListAdapter(mAdapter); mCallLogQueryHandler = new CallLogQueryHandler(getActivity().getContentResolver(), this, mLogLimit); mKeyguardManager = Loading @@ -201,9 +201,8 @@ public class CallLogFragment extends ListFragment // This will update the state of the "Clear call log" menu item. getActivity().invalidateOptionsMenu(); final ListView listView = getListView(); boolean showListView = cursor.getCount() > 0; listView.setVisibility(showListView ? View.VISIBLE : View.GONE); mRecyclerView.setVisibility(showListView ? View.VISIBLE : View.GONE); mEmptyListView.setVisibility(!showListView ? View.VISIBLE : View.GONE); if (mScrollToTop) { Loading @@ -213,8 +212,9 @@ public class CallLogFragment extends ListFragment // will not experience the illusion of downward motion. Instead, // if we're not already near the top of the list, we instantly jump // near the top, and animate from there. if (listView.getFirstVisiblePosition() > 5) { listView.setSelection(5); if (mLayoutManager.findFirstVisibleItemPosition() > 5) { // TODO: Jump to near the top, then begin smooth scroll. mRecyclerView.smoothScrollToPosition(0); } // Workaround for framework issue: the smooth-scroll doesn't // occur if setSelection() is called immediately before. Loading @@ -224,7 +224,7 @@ public class CallLogFragment extends ListFragment if (getActivity() == null || getActivity().isFinishing()) { return; } listView.smoothScrollToPosition(0); mRecyclerView.smoothScrollToPosition(0); } }); Loading Loading @@ -269,6 +269,17 @@ public class CallLogFragment extends ListFragment @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedState) { View view = inflater.inflate(R.layout.call_log_fragment, container, false); mRecyclerView = (RecyclerView) view.findViewById(R.id.recycler_view); mRecyclerView.setHasFixedSize(true); mLayoutManager = new LinearLayoutManager(getActivity()); mRecyclerView.setLayoutManager(mLayoutManager); String currentCountryIso = GeoUtil.getCurrentCountryIso(getActivity()); mAdapter = ObjectFactory.newCallLogAdapter(getActivity(), this, new ContactInfoHelper(getActivity(), currentCountryIso), this); mRecyclerView.setAdapter(mAdapter); mVoicemailStatusHelper = new VoicemailStatusHelperImpl(); mStatusMessageView = view.findViewById(R.id.voicemail_status); mStatusMessageText = (TextView) view.findViewById(R.id.voicemail_status_message); Loading @@ -280,7 +291,6 @@ public class CallLogFragment extends ListFragment public void onViewCreated(View view, Bundle savedInstanceState) { super.onViewCreated(view, savedInstanceState); mEmptyListView = view.findViewById(R.id.empty_list_view); getListView().setItemsCanFocus(true); updateEmptyMessage(mCallTypeFilter); } Loading src/com/android/dialer/calllog/CallLogListItemViews.java +3 −1 Original line number Diff line number Diff line Loading @@ -20,6 +20,7 @@ import android.content.Context; import android.content.res.Resources; import android.net.Uri; import android.provider.CallLog.Calls; import android.support.v7.widget.RecyclerView; import android.telecom.PhoneAccountHandle; import android.text.TextUtils; import android.view.View; Loading @@ -44,7 +45,7 @@ import com.android.dialer.R; * is a way of isolating view logic from the CallLogAdapter. We should consider moving that logic * if the call log list item is eventually represented as a UI component. */ public final class CallLogListItemViews { public final class CallLogListItemViews extends RecyclerView.ViewHolder { /** The root view of the call log list item */ public final View rootView; /** The quick contact badge for the contact. */ Loading Loading @@ -147,6 +148,7 @@ public final class CallLogListItemViews { PhoneCallDetailsViews phoneCallDetailsViews, View callLogEntryView, TextView dayGroupHeader) { super(rootView); mContext = context; this.rootView = rootView; Loading src/com/android/dialer/calllog/GroupingListAdapter.java +19 −60 Original line number Diff line number Diff line Loading @@ -21,6 +21,8 @@ import android.database.ContentObserver; import android.database.Cursor; import android.database.DataSetObserver; import android.os.Handler; import android.support.v7.widget.RecyclerView; import android.util.Log; import android.util.SparseIntArray; import android.view.View; import android.view.ViewGroup; Loading @@ -34,7 +36,7 @@ import com.android.contacts.common.testing.NeededForTesting; * The list has three types of elements: stand-alone, group header and group child. Groups are * collapsible and collapsed by default. This is used by the call log to group related entries. */ abstract class GroupingListAdapter extends BaseAdapter { abstract class GroupingListAdapter extends RecyclerView.Adapter { private static final int GROUP_METADATA_ARRAY_INITIAL_SIZE = 16; private static final int GROUP_METADATA_ARRAY_INCREMENT = 128; Loading Loading @@ -109,11 +111,6 @@ abstract class GroupingListAdapter extends BaseAdapter { public void onChanged() { notifyDataSetChanged(); } @Override public void onInvalidated() { notifyDataSetInvalidated(); } }; public GroupingListAdapter(Context context) { Loading @@ -127,15 +124,7 @@ abstract class GroupingListAdapter extends BaseAdapter { */ protected abstract void addGroups(Cursor cursor); protected abstract View newStandAloneView(Context context, ViewGroup parent); protected abstract void bindStandAloneView(View view, Context context, Cursor cursor); protected abstract View newGroupView(Context context, ViewGroup parent); protected abstract void bindGroupView(View view, Context context, Cursor cursor, int groupSize, boolean expanded); protected abstract View newChildView(Context context, ViewGroup parent); protected abstract void bindChildView(View view, Context context, Cursor cursor); protected abstract void onContentChanged(); /** * Cache should be reset whenever the cursor changes or groups are expanded or collapsed. Loading @@ -149,9 +138,6 @@ abstract class GroupingListAdapter extends BaseAdapter { mPositionCache.clear(); } protected void onContentChanged() { } public void changeCursor(Cursor cursor) { if (cursor == mCursor) { return; Loading @@ -171,13 +157,10 @@ abstract class GroupingListAdapter extends BaseAdapter { cursor.registerDataSetObserver(mDataSetObserver); mRowIdColumnIndex = cursor.getColumnIndexOrThrow("_id"); notifyDataSetChanged(); } else { // notify the observers about the lack of a data set notifyDataSetInvalidated(); } } @NeededForTesting public Cursor getCursor() { return mCursor; } Loading Loading @@ -231,7 +214,8 @@ abstract class GroupingListAdapter extends BaseAdapter { return need; } public int getCount() { @Override public int getItemCount() { if (mCursor == null) { return 0; } Loading Loading @@ -343,6 +327,7 @@ abstract class GroupingListAdapter extends BaseAdapter { if (position < listPosition) { metadata.itemType = ITEM_TYPE_STANDALONE; metadata.cursorPosition = cursorPosition - (listPosition - position); metadata.childCount = 1; return; } Loading Loading @@ -382,6 +367,7 @@ abstract class GroupingListAdapter extends BaseAdapter { // The required item is past the last group metadata.itemType = ITEM_TYPE_STANDALONE; metadata.cursorPosition = cursorPosition + (position - listPosition); metadata.childCount = 1; } /** Loading Loading @@ -421,12 +407,6 @@ abstract class GroupingListAdapter extends BaseAdapter { notifyDataSetChanged(); } @Override public int getViewTypeCount() { return 3; } @Override public int getItemViewType(int position) { obtainPositionMetadata(mPositionMetadata, position); return mPositionMetadata.itemType; Loading Loading @@ -454,37 +434,16 @@ abstract class GroupingListAdapter extends BaseAdapter { } } public View getView(int position, View convertView, ViewGroup parent) { obtainPositionMetadata(mPositionMetadata, position); View view = convertView; if (view == null) { switch (mPositionMetadata.itemType) { case ITEM_TYPE_STANDALONE: view = newStandAloneView(mContext, parent); break; case ITEM_TYPE_GROUP_HEADER: view = newGroupView(mContext, parent); break; case ITEM_TYPE_IN_GROUP: view = newChildView(mContext, parent); break; } } mCursor.moveToPosition(mPositionMetadata.cursorPosition); switch (mPositionMetadata.itemType) { case ITEM_TYPE_STANDALONE: bindStandAloneView(view, mContext, mCursor); break; case ITEM_TYPE_GROUP_HEADER: bindGroupView(view, mContext, mCursor, mPositionMetadata.childCount, mPositionMetadata.isExpanded); break; case ITEM_TYPE_IN_GROUP: bindChildView(view, mContext, mCursor); break; } return view; /** * Used for setting the cursor without triggering a UI thread update. */ @NeededForTesting public void setCursorForTesting(Cursor cursor) { if (cursor != null) { mCursor = cursor; cursor.registerContentObserver(mChangeObserver); cursor.registerDataSetObserver(mDataSetObserver); mRowIdColumnIndex = cursor.getColumnIndexOrThrow("_id"); } } } Loading
res/layout/call_log_fragment.xml +3 −10 Original line number Diff line number Diff line Loading @@ -61,18 +61,11 @@ <FrameLayout android:layout_width="match_parent" android:layout_height="match_parent"> <!-- clipChildren=false is required to ensure shadows drawn within list items aren't clipped by the list item bounds. --> <ListView android:id="@android:id/list" <android.support.v7.widget.RecyclerView android:id="@+id/recycler_view" android:layout_width="match_parent" android:layout_height="match_parent" android:fadingEdge="none" android:scrollbarStyle="outsideOverlay" android:background="@color/background_dialer_list_items" android:divider="@null" android:nestedScrollingEnabled="true" android:clipChildren="false" /> android:background="@color/background_dialer_list_items" /> <include android:id="@+id/empty_list_view" Loading
src/com/android/dialer/calllog/CallLogAdapter.java +16 −40 Original line number Diff line number Diff line Loading @@ -23,6 +23,7 @@ import android.database.Cursor; import android.net.Uri; import android.provider.ContactsContract.CommonDataKinds.Phone; import android.provider.ContactsContract.PhoneLookup; import android.support.v7.widget.RecyclerView.ViewHolder; import android.telecom.PhoneAccountHandle; import android.telephony.PhoneNumberUtils; import android.text.TextUtils; Loading Loading @@ -225,13 +226,12 @@ public class CallLogAdapter extends GroupingListAdapter mLoading = loading; } @Override public boolean isEmpty() { if (mLoading) { // We don't want the empty state to show when loading. return false; } else { return super.isEmpty(); return getItemCount() == 0; } } Loading Loading @@ -262,48 +262,19 @@ public class CallLogAdapter extends GroupingListAdapter } @Override protected View newStandAloneView(Context context, ViewGroup parent) { return newChildView(context, parent); } @Override protected View newGroupView(Context context, ViewGroup parent) { return newChildView(context, parent); } @Override protected View newChildView(Context context, ViewGroup parent) { LayoutInflater inflater = LayoutInflater.from(context); public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { LayoutInflater inflater = LayoutInflater.from(mContext); View view = inflater.inflate(R.layout.call_log_list_item, parent, false); // Get the views to bind to and cache them. CallLogListItemViews views = CallLogListItemViews.fromView(context, view); CallLogListItemViews views = CallLogListItemViews.fromView(mContext, view); view.setTag(views); // Set text height to false on the TextViews so they don't have extra padding. views.phoneCallDetailsViews.nameView.setElegantTextHeight(false); views.phoneCallDetailsViews.callLocationAndDate.setElegantTextHeight(false); return view; } @Override protected void bindStandAloneView(View view, Context context, Cursor cursor) { bindView(view, cursor, 1); } @Override protected void bindChildView(View view, Context context, Cursor cursor) { bindView(view, cursor, 1); } @Override protected void bindGroupView(View view, Context context, Cursor cursor, int groupSize, boolean expanded) { bindView(view, cursor, groupSize); } private void findAndCacheViews(View view) { return (CallLogListItemViews) view.getTag(); } /** Loading @@ -312,12 +283,17 @@ public class CallLogAdapter extends GroupingListAdapter * should not. It invokes cross-process methods and the repeat execution can get costly. * * @param callLogItemView the view corresponding to this entry * @param c the cursor pointing to the entry in the call log * @param count the number of entries in the current item, greater than 1 if it is a group */ public void bindView(View callLogItemView, Cursor c, int count) { callLogItemView.setAccessibilityDelegate(mAccessibilityDelegate); final CallLogListItemViews views = (CallLogListItemViews) callLogItemView.getTag(); public void onBindViewHolder(ViewHolder viewHolder, int position) { Cursor c = (Cursor) getItem(position); if (c == null) { return; } int count = getGroupSize(position); CallLogListItemViews views = (CallLogListItemViews) viewHolder; views.rootView.setAccessibilityDelegate(mAccessibilityDelegate); // Default case: an item in the call log. views.primaryActionView.setVisibility(View.VISIBLE); Loading Loading @@ -435,7 +411,7 @@ public class CallLogAdapter extends GroupingListAdapter // Listen for the first draw if (mViewTreeObserver == null) { mViewTreeObserver = callLogItemView.getViewTreeObserver(); mViewTreeObserver = views.rootView.getViewTreeObserver(); mViewTreeObserver.addOnPreDrawListener(this); } } Loading
src/com/android/dialer/calllog/CallLogFragment.java +22 −12 Original line number Diff line number Diff line Loading @@ -21,8 +21,8 @@ import android.animation.AnimatorListenerAdapter; import android.animation.ValueAnimator; import android.app.Activity; import android.app.DialogFragment; import android.app.Fragment; import android.app.KeyguardManager; import android.app.ListFragment; import android.content.Context; import android.content.Intent; import android.database.ContentObserver; Loading @@ -34,10 +34,11 @@ import android.provider.CallLog; import android.provider.CallLog.Calls; import android.provider.ContactsContract; import android.provider.VoicemailContract.Status; import android.support.v7.widget.RecyclerView; import android.support.v7.widget.LinearLayoutManager; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.view.ViewTreeObserver; import android.view.View.OnClickListener; import android.view.ViewGroup.LayoutParams; import android.widget.ListView; Loading @@ -60,7 +61,7 @@ import java.util.List; * Displays a list of call log entries. To filter for a particular kind of call * (all, missed or voicemails), specify it in the constructor. */ public class CallLogFragment extends ListFragment public class CallLogFragment extends Fragment implements CallLogQueryHandler.Listener, CallLogAdapter.OnReportButtonClickListener, CallLogAdapter.CallFetcher { private static final String TAG = "CallLogFragment"; Loading @@ -76,6 +77,8 @@ public class CallLogFragment extends ListFragment private static final String KEY_LOG_LIMIT = "log_limit"; private static final String KEY_DATE_LIMIT = "date_limit"; private RecyclerView mRecyclerView; private LinearLayoutManager mLayoutManager; private CallLogAdapter mAdapter; private CallLogQueryHandler mCallLogQueryHandler; private boolean mScrollToTop; Loading Loading @@ -172,9 +175,6 @@ public class CallLogFragment extends ListFragment } String currentCountryIso = GeoUtil.getCurrentCountryIso(getActivity()); mAdapter = ObjectFactory.newCallLogAdapter(getActivity(), this, new ContactInfoHelper(getActivity(), currentCountryIso), this); setListAdapter(mAdapter); mCallLogQueryHandler = new CallLogQueryHandler(getActivity().getContentResolver(), this, mLogLimit); mKeyguardManager = Loading @@ -201,9 +201,8 @@ public class CallLogFragment extends ListFragment // This will update the state of the "Clear call log" menu item. getActivity().invalidateOptionsMenu(); final ListView listView = getListView(); boolean showListView = cursor.getCount() > 0; listView.setVisibility(showListView ? View.VISIBLE : View.GONE); mRecyclerView.setVisibility(showListView ? View.VISIBLE : View.GONE); mEmptyListView.setVisibility(!showListView ? View.VISIBLE : View.GONE); if (mScrollToTop) { Loading @@ -213,8 +212,9 @@ public class CallLogFragment extends ListFragment // will not experience the illusion of downward motion. Instead, // if we're not already near the top of the list, we instantly jump // near the top, and animate from there. if (listView.getFirstVisiblePosition() > 5) { listView.setSelection(5); if (mLayoutManager.findFirstVisibleItemPosition() > 5) { // TODO: Jump to near the top, then begin smooth scroll. mRecyclerView.smoothScrollToPosition(0); } // Workaround for framework issue: the smooth-scroll doesn't // occur if setSelection() is called immediately before. Loading @@ -224,7 +224,7 @@ public class CallLogFragment extends ListFragment if (getActivity() == null || getActivity().isFinishing()) { return; } listView.smoothScrollToPosition(0); mRecyclerView.smoothScrollToPosition(0); } }); Loading Loading @@ -269,6 +269,17 @@ public class CallLogFragment extends ListFragment @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedState) { View view = inflater.inflate(R.layout.call_log_fragment, container, false); mRecyclerView = (RecyclerView) view.findViewById(R.id.recycler_view); mRecyclerView.setHasFixedSize(true); mLayoutManager = new LinearLayoutManager(getActivity()); mRecyclerView.setLayoutManager(mLayoutManager); String currentCountryIso = GeoUtil.getCurrentCountryIso(getActivity()); mAdapter = ObjectFactory.newCallLogAdapter(getActivity(), this, new ContactInfoHelper(getActivity(), currentCountryIso), this); mRecyclerView.setAdapter(mAdapter); mVoicemailStatusHelper = new VoicemailStatusHelperImpl(); mStatusMessageView = view.findViewById(R.id.voicemail_status); mStatusMessageText = (TextView) view.findViewById(R.id.voicemail_status_message); Loading @@ -280,7 +291,6 @@ public class CallLogFragment extends ListFragment public void onViewCreated(View view, Bundle savedInstanceState) { super.onViewCreated(view, savedInstanceState); mEmptyListView = view.findViewById(R.id.empty_list_view); getListView().setItemsCanFocus(true); updateEmptyMessage(mCallTypeFilter); } Loading
src/com/android/dialer/calllog/CallLogListItemViews.java +3 −1 Original line number Diff line number Diff line Loading @@ -20,6 +20,7 @@ import android.content.Context; import android.content.res.Resources; import android.net.Uri; import android.provider.CallLog.Calls; import android.support.v7.widget.RecyclerView; import android.telecom.PhoneAccountHandle; import android.text.TextUtils; import android.view.View; Loading @@ -44,7 +45,7 @@ import com.android.dialer.R; * is a way of isolating view logic from the CallLogAdapter. We should consider moving that logic * if the call log list item is eventually represented as a UI component. */ public final class CallLogListItemViews { public final class CallLogListItemViews extends RecyclerView.ViewHolder { /** The root view of the call log list item */ public final View rootView; /** The quick contact badge for the contact. */ Loading Loading @@ -147,6 +148,7 @@ public final class CallLogListItemViews { PhoneCallDetailsViews phoneCallDetailsViews, View callLogEntryView, TextView dayGroupHeader) { super(rootView); mContext = context; this.rootView = rootView; Loading
src/com/android/dialer/calllog/GroupingListAdapter.java +19 −60 Original line number Diff line number Diff line Loading @@ -21,6 +21,8 @@ import android.database.ContentObserver; import android.database.Cursor; import android.database.DataSetObserver; import android.os.Handler; import android.support.v7.widget.RecyclerView; import android.util.Log; import android.util.SparseIntArray; import android.view.View; import android.view.ViewGroup; Loading @@ -34,7 +36,7 @@ import com.android.contacts.common.testing.NeededForTesting; * The list has three types of elements: stand-alone, group header and group child. Groups are * collapsible and collapsed by default. This is used by the call log to group related entries. */ abstract class GroupingListAdapter extends BaseAdapter { abstract class GroupingListAdapter extends RecyclerView.Adapter { private static final int GROUP_METADATA_ARRAY_INITIAL_SIZE = 16; private static final int GROUP_METADATA_ARRAY_INCREMENT = 128; Loading Loading @@ -109,11 +111,6 @@ abstract class GroupingListAdapter extends BaseAdapter { public void onChanged() { notifyDataSetChanged(); } @Override public void onInvalidated() { notifyDataSetInvalidated(); } }; public GroupingListAdapter(Context context) { Loading @@ -127,15 +124,7 @@ abstract class GroupingListAdapter extends BaseAdapter { */ protected abstract void addGroups(Cursor cursor); protected abstract View newStandAloneView(Context context, ViewGroup parent); protected abstract void bindStandAloneView(View view, Context context, Cursor cursor); protected abstract View newGroupView(Context context, ViewGroup parent); protected abstract void bindGroupView(View view, Context context, Cursor cursor, int groupSize, boolean expanded); protected abstract View newChildView(Context context, ViewGroup parent); protected abstract void bindChildView(View view, Context context, Cursor cursor); protected abstract void onContentChanged(); /** * Cache should be reset whenever the cursor changes or groups are expanded or collapsed. Loading @@ -149,9 +138,6 @@ abstract class GroupingListAdapter extends BaseAdapter { mPositionCache.clear(); } protected void onContentChanged() { } public void changeCursor(Cursor cursor) { if (cursor == mCursor) { return; Loading @@ -171,13 +157,10 @@ abstract class GroupingListAdapter extends BaseAdapter { cursor.registerDataSetObserver(mDataSetObserver); mRowIdColumnIndex = cursor.getColumnIndexOrThrow("_id"); notifyDataSetChanged(); } else { // notify the observers about the lack of a data set notifyDataSetInvalidated(); } } @NeededForTesting public Cursor getCursor() { return mCursor; } Loading Loading @@ -231,7 +214,8 @@ abstract class GroupingListAdapter extends BaseAdapter { return need; } public int getCount() { @Override public int getItemCount() { if (mCursor == null) { return 0; } Loading Loading @@ -343,6 +327,7 @@ abstract class GroupingListAdapter extends BaseAdapter { if (position < listPosition) { metadata.itemType = ITEM_TYPE_STANDALONE; metadata.cursorPosition = cursorPosition - (listPosition - position); metadata.childCount = 1; return; } Loading Loading @@ -382,6 +367,7 @@ abstract class GroupingListAdapter extends BaseAdapter { // The required item is past the last group metadata.itemType = ITEM_TYPE_STANDALONE; metadata.cursorPosition = cursorPosition + (position - listPosition); metadata.childCount = 1; } /** Loading Loading @@ -421,12 +407,6 @@ abstract class GroupingListAdapter extends BaseAdapter { notifyDataSetChanged(); } @Override public int getViewTypeCount() { return 3; } @Override public int getItemViewType(int position) { obtainPositionMetadata(mPositionMetadata, position); return mPositionMetadata.itemType; Loading Loading @@ -454,37 +434,16 @@ abstract class GroupingListAdapter extends BaseAdapter { } } public View getView(int position, View convertView, ViewGroup parent) { obtainPositionMetadata(mPositionMetadata, position); View view = convertView; if (view == null) { switch (mPositionMetadata.itemType) { case ITEM_TYPE_STANDALONE: view = newStandAloneView(mContext, parent); break; case ITEM_TYPE_GROUP_HEADER: view = newGroupView(mContext, parent); break; case ITEM_TYPE_IN_GROUP: view = newChildView(mContext, parent); break; } } mCursor.moveToPosition(mPositionMetadata.cursorPosition); switch (mPositionMetadata.itemType) { case ITEM_TYPE_STANDALONE: bindStandAloneView(view, mContext, mCursor); break; case ITEM_TYPE_GROUP_HEADER: bindGroupView(view, mContext, mCursor, mPositionMetadata.childCount, mPositionMetadata.isExpanded); break; case ITEM_TYPE_IN_GROUP: bindChildView(view, mContext, mCursor); break; } return view; /** * Used for setting the cursor without triggering a UI thread update. */ @NeededForTesting public void setCursorForTesting(Cursor cursor) { if (cursor != null) { mCursor = cursor; cursor.registerContentObserver(mChangeObserver); cursor.registerDataSetObserver(mDataSetObserver); mRowIdColumnIndex = cursor.getColumnIndexOrThrow("_id"); } } }