From efb2d9c2e32ca4ed434ff785c4b3d18c9e08db6d Mon Sep 17 00:00:00 2001 From: Yorke Lee Date: Fri, 18 Apr 2014 14:05:01 -0700 Subject: Use PhoneFavoritesTileAdapter directly in GridView This CL moves the adapter that contains the speed dial contacts into its own GridView that lives in PhoneFavoritesFragment. This is the first step to splitting up PhoneFavoritesMergedAdapter into a list of shortcuts and a grid of contacts, and also get rid of the convoluted ContactTileRow logic within PhoneFavoritesTileAdapter, to facilitate a future transition to RecyclerView. * PhoneFavoritesTileAdapter now directly returns PhoneFavoriteTileViews rather than ContactTileRows. * Deleted a lot of unnecessary complicated logic within PhoneFavoritesTileAdapter that had to do with ContactTileRows. * Simplified and rewrote animation logic so that animations now perform as expected within the GridView. In the future this may not be necessary if RecyclerView is used. * Rewrote layout/measurement logic for PhoneFavoriteTileView. It now determines its height directly based on what its measured width is. * Replaced PhoneFavoritesListView in PhoneFavoriteFragment with a standard GridView * Delete stale PhoneFavoriteTileAdapter tests Notes: Call shortcut cards are now temporarily missing due to this change Bug: 13963734 Bug: 13933092 Bug: 13419223 Change-Id: I71e8970667589e4024d00e9af2c8b45c843c5db1 --- src/com/android/dialer/DialtactsActivity.java | 5 +- .../android/dialer/list/DragDropController.java | 28 +- .../android/dialer/list/OnDragDropListener.java | 10 +- .../android/dialer/list/PhoneFavoriteFragment.java | 167 ++------ .../android/dialer/list/PhoneFavoriteListView.java | 37 +- .../dialer/list/PhoneFavoriteMergedAdapter.java | 9 - .../dialer/list/PhoneFavoriteSquareTileView.java | 35 +- .../android/dialer/list/PhoneFavoriteTileView.java | 12 - .../dialer/list/PhoneFavoritesTileAdapter.java | 455 ++------------------- 9 files changed, 125 insertions(+), 633 deletions(-) (limited to 'src') diff --git a/src/com/android/dialer/DialtactsActivity.java b/src/com/android/dialer/DialtactsActivity.java index db4ff35eb..2d5df2b11 100644 --- a/src/com/android/dialer/DialtactsActivity.java +++ b/src/com/android/dialer/DialtactsActivity.java @@ -76,6 +76,7 @@ import com.android.dialer.list.OnDragDropListener; import com.android.dialer.list.OnListFragmentScrolledListener; import com.android.dialer.list.PhoneFavoriteFragment; import com.android.dialer.list.PhoneFavoriteTileView; +import com.android.dialer.list.PhoneFavoriteSquareTileView; import com.android.dialer.list.RegularSearchFragment; import com.android.dialer.list.RemoveView; import com.android.dialer.list.SearchFragment; @@ -915,13 +916,13 @@ public class DialtactsActivity extends TransactionSafeActivity implements View.O * Called when the user has long-pressed a contact tile to start a drag operation. */ @Override - public void onDragStarted(int itemIndex, int x, int y, PhoneFavoriteTileView view) { + public void onDragStarted(int x, int y, PhoneFavoriteSquareTileView view) { getActionBar().hide(); mSearchAndRemoveViewContainer.setVisibility(View.VISIBLE); } @Override - public void onDragHovered(int itemIndex, int x, int y) {} + public void onDragHovered(int x, int y, PhoneFavoriteSquareTileView view) {} /** * Called when the user has released a contact tile after long-pressing it. diff --git a/src/com/android/dialer/list/DragDropController.java b/src/com/android/dialer/list/DragDropController.java index 399cd099b..db4dd5937 100644 --- a/src/com/android/dialer/list/DragDropController.java +++ b/src/com/android/dialer/list/DragDropController.java @@ -1,9 +1,5 @@ package com.android.dialer.list; -import android.view.View; - -import com.android.dialer.list.PhoneFavoritesTileAdapter.ContactTileRow; - import java.util.ArrayList; import java.util.List; @@ -17,30 +13,22 @@ public class DragDropController { /** * @return True if the drag is started, false if the drag is cancelled for some reason. */ - boolean handleDragStarted(int x, int y, ContactTileRow tileRow) { - final PhoneFavoriteTileView tileView = - (PhoneFavoriteTileView) tileRow.getViewAtPosition(x, y); - - final int itemIndex = tileRow.getItemIndex(x, y); - if (itemIndex != -1 && !mOnDragDropListeners.isEmpty()) { + boolean handleDragStarted(int x, int y, PhoneFavoriteSquareTileView tileView) { + if (tileView == null) { + return false; + } + if (tileView != null && !mOnDragDropListeners.isEmpty()) { for (int i = 0; i < mOnDragDropListeners.size(); i++) { - mOnDragDropListeners.get(i).onDragStarted(itemIndex, x, y, tileView); + mOnDragDropListeners.get(i).onDragStarted(x, y, tileView); } } return true; } - public void handleDragHovered(int x, int y, View view) { - int itemIndex; - if (!(view instanceof ContactTileRow)) { - itemIndex = -1; - } else { - final ContactTileRow tile = (ContactTileRow) view; - itemIndex = tile.getItemIndex(x, y); - } + public void handleDragHovered(int x, int y, PhoneFavoriteSquareTileView view) { for (int i = 0; i < mOnDragDropListeners.size(); i++) { - mOnDragDropListeners.get(i).onDragHovered(itemIndex, x, y); + mOnDragDropListeners.get(i).onDragHovered(x, y, view); } } diff --git a/src/com/android/dialer/list/OnDragDropListener.java b/src/com/android/dialer/list/OnDragDropListener.java index 7f6d1791c..c9ef50b09 100644 --- a/src/com/android/dialer/list/OnDragDropListener.java +++ b/src/com/android/dialer/list/OnDragDropListener.java @@ -8,22 +8,22 @@ package com.android.dialer.list; public interface OnDragDropListener { /** * Called when a drag is started. - * @param itemIndex Index of the contact on which the drag was triggered * @param x X-coordinate of the drag event * @param y Y-coordinate of the drag event * @param view The contact tile which the drag was started on */ - public void onDragStarted(int itemIndex, int x, int y, PhoneFavoriteTileView view); + public void onDragStarted(int x, int y, PhoneFavoriteSquareTileView view); /** * Called when a drag is in progress and the user moves the dragged contact to a * location. - * @param itemIndex Index of the contact in the ListView which is currently being displaced - * by the dragged contact + * * @param x X-coordinate of the drag event * @param y Y-coordinate of the drag event + * @param view Contact tile in the ListView which is currently being displaced + * by the dragged contact */ - public void onDragHovered(int itemIndex, int x, int y); + public void onDragHovered(int x, int y, PhoneFavoriteSquareTileView view); /** * Called when a drag is completed (whether by dropping it somewhere or simply by dragging diff --git a/src/com/android/dialer/list/PhoneFavoriteFragment.java b/src/com/android/dialer/list/PhoneFavoriteFragment.java index f3787e5b8..ed6b5c810 100644 --- a/src/com/android/dialer/list/PhoneFavoriteFragment.java +++ b/src/com/android/dialer/list/PhoneFavoriteFragment.java @@ -49,7 +49,6 @@ import com.android.contacts.common.ContactPhotoManager; import com.android.contacts.common.ContactTileLoaderFactory; import com.android.contacts.common.GeoUtil; import com.android.contacts.common.list.ContactEntry; -import com.android.contacts.common.list.ContactListItemView; import com.android.contacts.common.list.ContactTileView; import com.android.contacts.common.list.OnPhoneNumberPickerActionListener; import com.android.dialer.DialtactsActivity; @@ -58,7 +57,6 @@ import com.android.dialer.calllog.CallLogAdapter; import com.android.dialer.calllog.CallLogQuery; import com.android.dialer.calllog.CallLogQueryHandler; import com.android.dialer.calllog.ContactInfoHelper; -import com.android.dialer.list.PhoneFavoritesTileAdapter.ContactTileRow; import com.android.dialerbind.ObjectFactory; import java.util.ArrayList; @@ -161,7 +159,7 @@ public class PhoneFavoriteFragment extends Fragment implements OnItemClickListen @Override public int getApproximateTileWidth() { - return getView().getWidth() / mContactTileAdapter.getColumnCount(); + return getView().getWidth(); } } @@ -233,9 +231,7 @@ public class PhoneFavoriteFragment extends Fragment implements OnItemClickListen // We don't construct the resultant adapter at this moment since it requires LayoutInflater // that will be available on onCreateView(). mContactTileAdapter = new PhoneFavoritesTileAdapter(activity, mContactTileAdapterListener, - this, - getResources().getInteger(R.integer.contact_tile_column_count_in_favorites), - PhoneFavoritesTileAdapter.NO_ROW_LIMIT); + this); mContactTileAdapter.setPhotoLoader(ContactPhotoManager.getInstance(activity)); } @@ -271,7 +267,6 @@ public class PhoneFavoriteFragment extends Fragment implements OnItemClickListen mParentView = inflater.inflate(R.layout.phone_favorites_fragment, container, false); mListView = (PhoneFavoriteListView) mParentView.findViewById(R.id.contact_tile_list); - mListView.setItemsCanFocus(true); mListView.setOnItemClickListener(this); mListView.setVerticalScrollBarEnabled(false); mListView.setVerticalScrollbarPosition(View.SCROLLBAR_POSITION_RIGHT); @@ -294,9 +289,10 @@ public class PhoneFavoriteFragment extends Fragment implements OnItemClickListen mAdapter = new PhoneFavoriteMergedAdapter(getActivity(), this, mContactTileAdapter, mCallLogAdapter, mPhoneFavoritesMenu, mTileInteractionTeaserView); + mTileInteractionTeaserView.setAdapter(mAdapter); - mListView.setAdapter(mAdapter); + mListView.setAdapter(mContactTileAdapter); mListView.setOnScrollListener(mScrollListener); mListView.setFastScrollEnabled(false); @@ -381,7 +377,6 @@ public class PhoneFavoriteFragment extends Fragment implements OnItemClickListen @Override public void onCallsFetched(Cursor cursor) { - animateListView(); mCallLogAdapter.setLoading(false); // Save the date of the most recent call log item @@ -412,7 +407,6 @@ public class PhoneFavoriteFragment extends Fragment implements OnItemClickListen * that slide views from their previous positions to their new ones, to give the appearance * that the views are sliding into their new positions. */ - @SuppressWarnings("unchecked") private void saveOffsets(int removedItemHeight) { final int firstVisiblePosition = mListView.getFirstVisiblePosition(); if (DEBUG) { @@ -421,114 +415,22 @@ public class PhoneFavoriteFragment extends Fragment implements OnItemClickListen for (int i = 0; i < mListView.getChildCount(); i++) { final View child = mListView.getChildAt(i); final int position = firstVisiblePosition + i; - final long itemId = mAdapter.getItemId(position); - final int itemViewType = mAdapter.getItemViewType(position); - if (itemViewType == PhoneFavoritesTileAdapter.ViewTypes.TOP && - child instanceof ContactTileRow) { - // This is a tiled row, so save horizontal offsets instead - saveHorizontalOffsets((ContactTileRow) child, (ArrayList) - mAdapter.getItem(position), - mAdapter.getAdjustedPositionInContactTileAdapter(position)); - } + final long itemId = mContactTileAdapter.getItemId(position); if (DEBUG) { Log.d(TAG, "Saving itemId: " + itemId + " for listview child " + i + " Top: " + child.getTop()); } mItemIdTopMap.put(itemId, child.getTop()); - } - - mItemIdTopMap.put(KEY_REMOVED_ITEM_HEIGHT, removedItemHeight); - } - - /** - * Saves the horizontal offsets for contacts that are displayed as tiles in a row. Saving - * these offsets allow us to animate tiles sliding left and right within the same row. - * See {@link #saveOffsets(int removedItemHeight)} - */ - private void saveHorizontalOffsets(ContactTileRow row, ArrayList list, - int currentRowIndex) { - for (int i = 0; i < list.size() && i < row.getChildCount(); i++) { - final View child = row.getChildAt(i); - if (child == null) { - continue; - } - final ContactEntry entry = list.get(i); - final long itemId = mContactTileAdapter.getAdjustedItemId(entry.id); - if (DEBUG) { - Log.d(TAG, "Saving itemId: " + itemId + " for tileview child " + i + " Left: " - + child.getTop()); - } - mItemIdTopMap.put(itemId, currentRowIndex); mItemIdLeftMap.put(itemId, child.getLeft()); } - } - - /* - * Performs a animations for a row of tiles - */ - private void performHorizontalAnimations(ContactTileRow row, ArrayList list, - long[] idsInPlace, int currentRow) { - if (mItemIdLeftMap.isEmpty()) { - return; - } - final AnimatorSet animSet = new AnimatorSet(); - final ArrayList animators = new ArrayList(); - for (int i = 0; i < list.size(); i++) { - final View child = row.getChildAt(i); - final ContactEntry entry = list.get(i); - final long itemId = mContactTileAdapter.getAdjustedItemId(entry.id); - - if (containsId(idsInPlace, itemId)) { - animators.add(ObjectAnimator.ofFloat( - child, "alpha", 0.0f, 1.0f)); - break; - } else { - Integer startLeft = mItemIdLeftMap.get(itemId); - int left = child.getLeft(); - - Integer startRow = mItemIdTopMap.get(itemId); - if (startRow != null) { - if (startRow > currentRow) { - // Item has shifted upwards to the previous row. - // It should now animate in from right to left. - startLeft = left + child.getWidth(); - } else if (startRow < currentRow) { - // Item has shifted downwards to the next row. - // It should now animate in from left to right. - startLeft = left - child.getWidth(); - } - // If the item hasn't shifted rows (startRow == currentRow), it either remains - // in the same position or has shifted left or right within its current row. - // Either way, startLeft has already been correctly saved and retrieved from - // mItemIdTopMap. - } - - if (startLeft != null) { - if (startLeft != left) { - int delta = startLeft - left; - if (DEBUG) { - Log.d(TAG, "Found itemId: " + itemId + " for tileview child " + i + - " Left: " + left + - " Delta: " + delta); - } - animators.add(ObjectAnimator.ofFloat( - child, "translationX", delta, 0.0f)); - } - } - } - } - if (animators.size() > 0) { - animSet.setDuration(mAnimationDuration).playTogether(animators); - animSet.start(); - } + mItemIdTopMap.put(KEY_REMOVED_ITEM_HEIGHT, removedItemHeight); } /* - * Performs animations for the list view. If the list item is a row of tiles, horizontal - * animations will be performed instead. + * Performs animations for the gridView */ - private void animateListView(final long... idsInPlace) { + private void animateGridView(final long... idsInPlace) { if (mItemIdTopMap.isEmpty()) { // Don't do animations if the database is being queried for the first time and // the previous item offsets have not been cached, or the user hasn't done anything @@ -536,8 +438,6 @@ public class PhoneFavoriteFragment extends Fragment implements OnItemClickListen return; } - final int removedItemHeight = mItemIdTopMap.get(KEY_REMOVED_ITEM_HEIGHT); - final ViewTreeObserver observer = mListView.getViewTreeObserver(); observer.addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() { @SuppressWarnings("unchecked") @@ -550,16 +450,8 @@ public class PhoneFavoriteFragment extends Fragment implements OnItemClickListen for (int i = 0; i < mListView.getChildCount(); i++) { final View child = mListView.getChildAt(i); int position = firstVisiblePosition + i; - final int itemViewType = mAdapter.getItemViewType(position); - if (itemViewType == PhoneFavoritesTileAdapter.ViewTypes.TOP && - child instanceof ContactTileRow) { - // This is a tiled row, so perform horizontal animations instead - performHorizontalAnimations((ContactTileRow) child, ( - ArrayList) mAdapter.getItem(position), idsInPlace, - mAdapter.getAdjustedPositionInContactTileAdapter(position)); - } - final long itemId = mAdapter.getItemId(position); + final long itemId = mContactTileAdapter.getItemId(position); if (containsId(idsInPlace, itemId)) { animators.add(ObjectAnimator.ofFloat( @@ -567,35 +459,32 @@ public class PhoneFavoriteFragment extends Fragment implements OnItemClickListen break; } else { Integer startTop = mItemIdTopMap.get(itemId); + Integer startLeft = mItemIdLeftMap.get(itemId); final int top = child.getTop(); - int delta = 0; + final int left = child.getLeft(); + int deltaX = 0; + int deltaY = 0; + + if (startLeft != null) { + if (startLeft != left) { + deltaX = startLeft - left; + animators.add(ObjectAnimator.ofFloat( + child, "translationX", deltaX, 0.0f)); + } + } + if (startTop != null) { if (startTop != top) { - delta = startTop - top; - } - } else if (!mItemIdLeftMap.containsKey(itemId)) { - // Animate new views along with the others. The catch is that they did - // not exist in the start state, so we must calculate their starting - // position based on neighboring views. - - final int itemHeight; - if (removedItemHeight == 0) { - itemHeight = child.getHeight() + mListView.getDividerHeight(); - } else { - itemHeight = removedItemHeight; + deltaY = startTop - top; + animators.add(ObjectAnimator.ofFloat( + child, "translationY", deltaY, 0.0f)); } - startTop = top + (i > 0 ? itemHeight : -itemHeight); - delta = startTop - top; } + if (DEBUG) { Log.d(TAG, "Found itemId: " + itemId + " for listview child " + i + " Top: " + top + - " Delta: " + delta); - } - - if (delta != 0) { - animators.add(ObjectAnimator.ofFloat( - child, "translationY", delta, 0.0f)); + " Delta: " + deltaY); } } } @@ -624,7 +513,7 @@ public class PhoneFavoriteFragment extends Fragment implements OnItemClickListen @Override public void onDataSetChangedForAnimation(long... idsInPlace) { - animateListView(idsInPlace); + animateGridView(idsInPlace); } @Override diff --git a/src/com/android/dialer/list/PhoneFavoriteListView.java b/src/com/android/dialer/list/PhoneFavoriteListView.java index 67dbf2dba..6c3d62a59 100644 --- a/src/com/android/dialer/list/PhoneFavoriteListView.java +++ b/src/com/android/dialer/list/PhoneFavoriteListView.java @@ -29,17 +29,15 @@ import android.view.DragEvent; import android.view.MotionEvent; import android.view.View; import android.view.ViewConfiguration; +import android.widget.GridView; import android.widget.ImageView; -import android.widget.ListView; import com.android.dialer.R; -import com.android.dialer.list.PhoneFavoritesTileAdapter.ContactTileRow; /** - * The ListView used to present a combined list of shortcut cards and contact speed-dial - * tiles. + * Viewgroup that presents the user's speed dial contacts in a grid. */ -public class PhoneFavoriteListView extends ListView implements OnDragDropListener { +public class PhoneFavoriteListView extends GridView implements OnDragDropListener { public static final String LOG_TAG = PhoneFavoriteListView.class.getSimpleName(); @@ -116,7 +114,6 @@ public class PhoneFavoriteListView extends ListView implements OnDragDropListene super(context, attrs, defStyle); mAnimationDuration = context.getResources().getInteger(R.integer.fade_duration); mTouchSlop = ViewConfiguration.get(context).getScaledPagingTouchSlop(); - setItemsCanFocus(true); mDragDropController.addOnDragDropListener(this); } @@ -146,7 +143,7 @@ public class PhoneFavoriteListView extends ListView implements OnDragDropListene final int eX = (int) event.getX(); final int eY = (int) event.getY(); switch (action) { - case DragEvent.ACTION_DRAG_STARTED: + case DragEvent.ACTION_DRAG_STARTED: { final int[] coordinates = new int[2]; getLocationOnScreen(coordinates); // Calculate the X and Y coordinates of the drag event relative to the view @@ -154,21 +151,26 @@ public class PhoneFavoriteListView extends ListView implements OnDragDropListene final int viewY = eY - coordinates[1]; final View child = getViewAtPosition(viewX, viewY); - if (!(child instanceof ContactTileRow)) { + if (!(child instanceof PhoneFavoriteSquareTileView)) { // Bail early. return false; } - final ContactTileRow tile = (ContactTileRow) child; - + final PhoneFavoriteSquareTileView tile = (PhoneFavoriteSquareTileView) child; if (!mDragDropController.handleDragStarted(viewX, viewY, tile)) { return false; } break; + } case DragEvent.ACTION_DRAG_LOCATION: mLastDragY = eY; - final View view = getViewAtPosition(eX, eY); - mDragDropController.handleDragHovered(eX, eY, view); + final View child = getViewAtPosition(eX, eY); + + PhoneFavoriteSquareTileView tile = null; + if (child instanceof PhoneFavoriteSquareTileView) { + tile = (PhoneFavoriteSquareTileView) child; + } + mDragDropController.handleDragHovered(eX, eY, tile); // Kick off {@link #mScrollHandler} if it's not started yet. if (!mIsDragScrollerRunning && // And if the distance traveled while dragging exceeds the touch slop @@ -213,7 +215,8 @@ public class PhoneFavoriteListView extends ListView implements OnDragDropListene View child; for (int childIdx = 0; childIdx < count; childIdx++) { child = getChildAt(childIdx); - if (y >= child.getTop() && y <= child.getBottom()) { + if (y >= child.getTop() && y <= child.getBottom() && x >= child.getLeft() + && x <= child.getRight()) { return child; } } @@ -231,7 +234,7 @@ public class PhoneFavoriteListView extends ListView implements OnDragDropListene } @Override - public void onDragStarted(int itemIndex, int x, int y, PhoneFavoriteTileView tileView) { + public void onDragStarted(int x, int y, PhoneFavoriteSquareTileView tileView) { if (mDragShadowOverlay == null) { return; } @@ -244,8 +247,8 @@ public class PhoneFavoriteListView extends ListView implements OnDragDropListene // Square tile is relative to the contact tile, // and contact tile is relative to this list view. - mDragShadowLeft = tileView.getLeft() + tileView.getParentRow().getLeft(); - mDragShadowTop = tileView.getTop() + tileView.getParentRow().getTop(); + mDragShadowLeft = tileView.getLeft(); + mDragShadowTop = tileView.getTop(); mDragShadowOverlay.setImageBitmap(mDragShadowBitmap); mDragShadowOverlay.setVisibility(VISIBLE); @@ -262,7 +265,7 @@ public class PhoneFavoriteListView extends ListView implements OnDragDropListene } @Override - public void onDragHovered(int itemIndex, int x, int y) { + public void onDragHovered(int x, int y, PhoneFavoriteSquareTileView tileView) { // Update the drag shadow location. mDragShadowLeft = x - mTouchOffsetToChildLeft; mDragShadowTop = y - mTouchOffsetToChildTop; diff --git a/src/com/android/dialer/list/PhoneFavoriteMergedAdapter.java b/src/com/android/dialer/list/PhoneFavoriteMergedAdapter.java index 849d6514a..e2b9bb2bf 100644 --- a/src/com/android/dialer/list/PhoneFavoriteMergedAdapter.java +++ b/src/com/android/dialer/list/PhoneFavoriteMergedAdapter.java @@ -276,14 +276,6 @@ public class PhoneFavoriteMergedAdapter extends BaseAdapter { // Favorites section final View view = mContactTileAdapter.getView(position, convertView, parent); - if (position >= mContactTileAdapter.getMaxTiledRows()) { - final FrameLayout frameLayout = (FrameLayout) view; - final View child = frameLayout.getChildAt(0); - FrameLayout.LayoutParams params = new FrameLayout.LayoutParams( - FrameLayout.LayoutParams.WRAP_CONTENT, - FrameLayout.LayoutParams.WRAP_CONTENT); - child.setLayoutParams(params); - } return view; } @@ -331,7 +323,6 @@ public class PhoneFavoriteMergedAdapter extends BaseAdapter { /** * The swipeable call log row. - * See also {@link PhoneFavoritesTileAdapter.ContactTileRow}. */ private class SwipeableCallLogRow extends FrameLayout implements SwipeHelperCallback { private SwipeHelper mSwipeHelper; diff --git a/src/com/android/dialer/list/PhoneFavoriteSquareTileView.java b/src/com/android/dialer/list/PhoneFavoriteSquareTileView.java index 181d602bc..0520ab49c 100644 --- a/src/com/android/dialer/list/PhoneFavoriteSquareTileView.java +++ b/src/com/android/dialer/list/PhoneFavoriteSquareTileView.java @@ -18,7 +18,6 @@ package com.android.dialer.list; import android.content.Context; import android.provider.ContactsContract.QuickContact; -import android.text.TextUtils; import android.util.AttributeSet; import android.view.View; import android.widget.ImageButton; @@ -26,18 +25,23 @@ import android.widget.ImageButton; import com.android.contacts.common.R; import com.android.contacts.common.list.ContactEntry; -import java.util.regex.Pattern; - /** - * Displays the contact's picture overlayed with their name - * in a perfect square. It also has an additional touch target for a secondary action. + * Displays the contact's picture overlaid with their name and number type in a tile. */ public class PhoneFavoriteSquareTileView extends PhoneFavoriteTileView { private static final String TAG = PhoneFavoriteSquareTileView.class.getSimpleName(); + + private final float mHeightToWidthRatio; + private ImageButton mSecondaryButton; + private ContactEntry mContactEntry; + public PhoneFavoriteSquareTileView(Context context, AttributeSet attrs) { super(context, attrs); + + mHeightToWidthRatio = getResources().getFraction( + R.dimen.contact_tile_height_to_width_ratio, 1, 1); } @Override @@ -50,7 +54,7 @@ public class PhoneFavoriteSquareTileView extends PhoneFavoriteTileView { @Override protected int getApproximateImageSize() { // The picture is the full size of the tile (minus some padding, but we can be generous) - return mListener.getApproximateTileWidth(); + return getWidth(); } private void launchQuickContact() { @@ -69,5 +73,24 @@ public class PhoneFavoriteSquareTileView extends PhoneFavoriteTileView { } }); } + mContactEntry = entry; + } + + @Override + protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { + final int width = MeasureSpec.getSize(widthMeasureSpec); + final int height = (int) (mHeightToWidthRatio * width); + final int count = getChildCount(); + for (int i = 0; i < count; i++) { + getChildAt(i).measure( + MeasureSpec.makeMeasureSpec(width, MeasureSpec.EXACTLY), + MeasureSpec.makeMeasureSpec(height, MeasureSpec.EXACTLY) + ); + } + setMeasuredDimension(width, height); + } + + public ContactEntry getContactEntry() { + return mContactEntry; } } diff --git a/src/com/android/dialer/list/PhoneFavoriteTileView.java b/src/com/android/dialer/list/PhoneFavoriteTileView.java index 7fe4eaa65..3626bcb93 100644 --- a/src/com/android/dialer/list/PhoneFavoriteTileView.java +++ b/src/com/android/dialer/list/PhoneFavoriteTileView.java @@ -29,7 +29,6 @@ import com.android.contacts.common.ContactPhotoManager.DefaultImageRequest; import com.android.contacts.common.list.ContactEntry; import com.android.contacts.common.list.ContactTileView; import com.android.dialer.R; -import com.android.dialer.list.PhoneFavoritesTileAdapter.ContactTileRow; /** * A light version of the {@link com.android.contacts.common.list.ContactTileView} that is used in @@ -49,8 +48,6 @@ public abstract class PhoneFavoriteTileView extends ContactTileView { private static final float DEFAULT_IMAGE_LETTER_OFFSET = -0.14f; private static final float DEFAULT_IMAGE_LETTER_SCALE = 0.70f; - /** The view that holds the list view row. */ - protected ContactTileRow mParentRow; /** View that contains the transparent shadow that is overlaid on top of the contact image. */ private View mShadowOverlay; @@ -65,10 +62,6 @@ public abstract class PhoneFavoriteTileView extends ContactTileView { super(context, attrs); } - public ContactTileRow getParentRow() { - return mParentRow; - } - @Override protected void onFinishInflate() { super.onFinishInflate(); @@ -107,11 +100,6 @@ public abstract class PhoneFavoriteTileView extends ContactTileView { } } - @Override - protected void onAttachedToWindow() { - mParentRow = (ContactTileRow) getParent(); - } - @Override protected boolean isDarkTheme() { return false; diff --git a/src/com/android/dialer/list/PhoneFavoritesTileAdapter.java b/src/com/android/dialer/list/PhoneFavoritesTileAdapter.java index 0438fbd6b..95f53c59e 100644 --- a/src/com/android/dialer/list/PhoneFavoritesTileAdapter.java +++ b/src/com/android/dialer/list/PhoneFavoritesTileAdapter.java @@ -76,7 +76,6 @@ public class PhoneFavoritesTileAdapter extends BaseAdapter implements private int mDropEntryIndex = -1; /** New position of the temporarily entered contact in the cache. */ private int mDragEnteredEntryIndex = -1; - private long mIdToKeepInPlace = -1; private boolean mAwaitingRemove = false; private boolean mDelayCursorUpdates = false; @@ -85,10 +84,6 @@ public class PhoneFavoritesTileAdapter extends BaseAdapter implements protected int mNumFrequents; protected int mNumStarred; - protected int mColumnCount; - private int mMaxTiledRows = ROW_LIMIT_DEFAULT; - private int mStarredIndex; - protected int mIdIndex; protected int mLookupIndex; protected int mPhotoUriIndex; @@ -100,11 +95,10 @@ public class PhoneFavoritesTileAdapter extends BaseAdapter implements private int mPhoneNumberTypeIndex; private int mPhoneNumberLabelIndex; private int mIsDefaultNumberIndex; + private int mStarredIndex; protected int mPinnedIndex; protected int mContactIdIndex; - private final int mPaddingInPixels; - /** Indicates whether a drag is in process. */ private boolean mInDragging = false; @@ -135,19 +129,14 @@ public class PhoneFavoritesTileAdapter extends BaseAdapter implements }; public PhoneFavoritesTileAdapter(Context context, ContactTileView.Listener listener, - OnDataSetChangedForAnimationListener dataSetChangedListener, - int numCols, int maxTiledRows) { + OnDataSetChangedForAnimationListener dataSetChangedListener) { mDataSetChangedListener = dataSetChangedListener; mListener = listener; mContext = context; mResources = context.getResources(); - mColumnCount = numCols; mNumFrequents = 0; - mMaxTiledRows = maxTiledRows; mContactEntries = new ArrayList(); - // Converting padding in dips to padding in pixels - mPaddingInPixels = mContext.getResources() - .getDimensionPixelSize(R.dimen.contact_tile_divider_width); + bindColumnIndices(); } @@ -156,14 +145,6 @@ public class PhoneFavoritesTileAdapter extends BaseAdapter implements mPhotoManager = photoLoader; } - public void setMaxRowCount(int maxRows) { - mMaxTiledRows = maxRows; - } - - public void setColumnCount(int columnCount) { - mColumnCount = columnCount; - } - /** * Indicates whether a drag is in process. * @@ -228,12 +209,7 @@ public class PhoneFavoritesTileAdapter extends BaseAdapter implements // cause a refresh of any views that rely on this data notifyDataSetChanged(); // about to start redraw - if (mIdToKeepInPlace != -1) { - mDataSetChangedListener.onDataSetChangedForAnimation(mIdToKeepInPlace); - } else { - mDataSetChangedListener.onDataSetChangedForAnimation(); - } - mIdToKeepInPlace = -1; + mDataSetChangedListener.onDataSetChangedForAnimation(); } } @@ -336,17 +312,6 @@ public class PhoneFavoritesTileAdapter extends BaseAdapter implements return cursor.getCount(); } - /** - * Loads a contact from the cached list. - * - * @param position Position of the Contact. - * @return Contact at the requested position. - */ - protected ContactEntry getContactEntryFromCache(int position) { - if (mContactEntries.size() <= position) return null; - return mContactEntries.get(position); - } - /** * Returns the number of frequents that will be displayed in the list. */ @@ -356,52 +321,11 @@ public class PhoneFavoritesTileAdapter extends BaseAdapter implements @Override public int getCount() { - if (mContactEntries == null || mContactEntries.isEmpty()) { + if (mContactEntries == null) { return 0; } - int total = mContactEntries.size(); - // The number of contacts that don't show up as tiles - final int nonTiledRows = Math.max(0, total - getMaxContactsInTiles()); - // The number of tiled rows - final int tiledRows = getRowCount(total - nonTiledRows); - return nonTiledRows + tiledRows; - } - - public int getMaxTiledRows() { - return mMaxTiledRows; - } - - /** - * Returns the number of rows required to show the provided number of entries - * with the current number of columns. - */ - protected int getRowCount(int entryCount) { - if (entryCount == 0) return 0; - final int nonLimitedRows = ((entryCount - 1) / mColumnCount) + 1; - if (mMaxTiledRows == NO_ROW_LIMIT) { - return nonLimitedRows; - } - return Math.min(mMaxTiledRows, nonLimitedRows); - } - - private int getMaxContactsInTiles() { - if (mMaxTiledRows == NO_ROW_LIMIT) { - return Integer.MAX_VALUE; - } - return mColumnCount * mMaxTiledRows; - } - - public int getRowIndex(int entryIndex) { - if (entryIndex < getMaxContactsInTiles()) { - return entryIndex / mColumnCount; - } else { - return entryIndex - mMaxTiledRows * (mColumnCount + 1); - } - } - - public int getColumnCount() { - return mColumnCount; + return mContactEntries.size(); } /** @@ -409,44 +333,8 @@ public class PhoneFavoritesTileAdapter extends BaseAdapter implements * on the row for the given position. */ @Override - public ArrayList getItem(int position) { - ArrayList resultList = new ArrayList(mColumnCount); - - final int entryIndex = getFirstContactEntryIndexForPosition(position); - - final int viewType = getItemViewType(position); - - final int columnCount; - if (viewType == ViewTypes.TOP) { - columnCount = mColumnCount; - } else { - columnCount = 1; - } - - for (int i = 0; i < columnCount; i++) { - final ContactEntry entry = getContactEntryFromCache(entryIndex + i); - if (entry == null) break; // less than mColumnCount contacts - resultList.add(entry); - } - - return resultList; - } - - /* - * Given a position in the adapter, returns the index of the first contact entry that is to be - * in that row. - */ - private int getFirstContactEntryIndexForPosition(int position) { - final int maxContactsInTiles = getMaxContactsInTiles(); - if (position < getRowCount(maxContactsInTiles)) { - // Contacts that appear as tiles - return position * mColumnCount; - } else { - // Contacts that appear as rows - // The actual position of the contact in the cursor is simply total the number of - // tiled contacts + the given position - return maxContactsInTiles + position - mMaxTiledRows; - } + public ContactEntry getItem(int position) { + return mContactEntries.get(position); } /** @@ -458,18 +346,7 @@ public class PhoneFavoritesTileAdapter extends BaseAdapter implements */ @Override public long getItemId(int position) { - return position; - } - - /** - * Calculates the stable itemId for a particular entry based on the entry's contact ID. This - * stable itemId is used for animation purposes. - */ - public long getAdjustedItemId(long id) { - if (mMaxTiledRows == NO_ROW_LIMIT) { - return id; - } - return mMaxTiledRows + id; + return getItem(position).id; } @Override @@ -479,7 +356,6 @@ public class PhoneFavoritesTileAdapter extends BaseAdapter implements @Override public boolean areAllItemsEnabled() { - // No dividers, so all items are enabled. return true; } @@ -504,32 +380,21 @@ public class PhoneFavoritesTileAdapter extends BaseAdapter implements int itemViewType = getItemViewType(position); - ContactTileRow contactTileRowView = null; + PhoneFavoriteTileView tileView = null; - if (convertView instanceof ContactTileRow) { - contactTileRowView = (ContactTileRow) convertView; + if (convertView instanceof PhoneFavoriteTileView) { + tileView = (PhoneFavoriteTileView) convertView; } - ArrayList contactList = getItem(position); - - if (contactTileRowView == null) { - // Creating new row if needed - contactTileRowView = new ContactTileRow(mContext, itemViewType, position); + if (tileView == null) { + tileView = (PhoneFavoriteTileView) View.inflate(mContext, + R.layout.phone_favorite_tile_view, null); } - - contactTileRowView.configureRow(contactList, position, position == getCount() - 1); - - return contactTileRowView; + tileView.setPhotoManager(mPhotoManager); + tileView.loadFromContact(getItem(position)); + return tileView; } - private int getLayoutResourceId(int viewType) { - switch (viewType) { - case ViewTypes.TOP: - return R.layout.phone_favorite_tile_view; - default: - throw new IllegalArgumentException("Unrecognized viewType " + viewType); - } - } @Override public int getViewTypeCount() { return ViewTypes.COUNT; @@ -537,7 +402,7 @@ public class PhoneFavoritesTileAdapter extends BaseAdapter implements @Override public int getItemViewType(int position) { - return ViewTypes.TOP; + return ViewTypes.TILE; } /** @@ -595,7 +460,6 @@ public class PhoneFavoritesTileAdapter extends BaseAdapter implements // populated with the dragged ContactEntry at the correct spot. mDropEntryIndex = mDragEnteredEntryIndex; mContactEntries.set(mDropEntryIndex, mDraggedEntry); - mIdToKeepInPlace = getAdjustedItemId(mDraggedEntry.id); mDataSetChangedListener.cacheOffsetsForDatasetChange(); changed = true; } else if (isIndexInBound(mDraggedEntryIndex)) { @@ -641,271 +505,9 @@ public class PhoneFavoritesTileAdapter extends BaseAdapter implements } /** - * Acts as a row item composed of {@link ContactTileView} - * - */ - public class ContactTileRow extends FrameLayout { - public static final int CONTACT_ENTRY_INDEX_TAG = R.id.contact_entry_index_tag; - - private int mItemViewType; - private int mLayoutResId; - private final int mRowPaddingStart; - private final int mRowPaddingEnd; - private final int mRowPaddingTop; - private final int mRowPaddingBottom; - private final float mHeightToWidthRatio; - private int mPosition; - - public ContactTileRow(Context context, int itemViewType, int position) { - super(context); - mItemViewType = itemViewType; - mLayoutResId = getLayoutResourceId(mItemViewType); - mPosition = position; - - final Resources resources = mContext.getResources(); - - mHeightToWidthRatio = getResources().getFraction( - R.dimen.contact_tile_height_to_width_ratio, 1, 1); - - if (mItemViewType == ViewTypes.TOP) { - // For tiled views, we still want padding to be set on the ContactTileRow. - // Otherwise the padding would be set around each of the tiles, which we don't want - mRowPaddingTop = resources.getDimensionPixelSize( - R.dimen.favorites_row_top_padding); - mRowPaddingBottom = resources.getDimensionPixelSize( - R.dimen.favorites_row_bottom_padding); - mRowPaddingStart = resources.getDimensionPixelSize( - R.dimen.favorites_row_start_padding); - mRowPaddingEnd = resources.getDimensionPixelSize( - R.dimen.favorites_row_end_padding); - } else { - // For row views, padding is set on the view itself. - mRowPaddingTop = 0; - mRowPaddingBottom = 0; - mRowPaddingStart = 0; - mRowPaddingEnd = 0; - } - - setPaddingRelative(mRowPaddingStart, mRowPaddingTop, mRowPaddingEnd, - mRowPaddingBottom); - - // Remove row (but not children) from accessibility node tree. - setImportantForAccessibility(View.IMPORTANT_FOR_ACCESSIBILITY_NO); - } - - /** - * Configures the row to add {@link ContactEntry}s information to the views - */ - public void configureRow(ArrayList list, int position, boolean isLastRow) { - final int columnCount = mColumnCount; - mPosition = position; - - // Adding tiles to row and filling in contact information - for (int columnCounter = 0; columnCounter < columnCount; columnCounter++) { - ContactEntry entry = - columnCounter < list.size() ? list.get(columnCounter) : null; - addTileFromEntry(entry, columnCounter, isLastRow); - } - } - - private void addTileFromEntry(ContactEntry entry, int childIndex, boolean isLastRow) { - final PhoneFavoriteTileView contactTile; - - if (getChildCount() <= childIndex) { - - contactTile = (PhoneFavoriteTileView) inflate(mContext, mLayoutResId, null); - // Note: the layoutparam set here is only actually used for FREQUENT. - // We override onMeasure() for STARRED and we don't care the layout param there. - final Resources resources = mContext.getResources(); - FrameLayout.LayoutParams params = new FrameLayout.LayoutParams( - ViewGroup.LayoutParams.WRAP_CONTENT, - ViewGroup.LayoutParams.WRAP_CONTENT); - - params.setMargins( - resources.getDimensionPixelSize(R.dimen.detail_item_side_margin), 0, - resources.getDimensionPixelSize(R.dimen.detail_item_side_margin), 0); - contactTile.setLayoutParams(params); - contactTile.setPhotoManager(mPhotoManager); - contactTile.setListener(mListener); - addView(contactTile); - } else { - contactTile = (PhoneFavoriteTileView) getChildAt(childIndex); - } - contactTile.loadFromContact(entry); - - int entryIndex = -1; - switch (mItemViewType) { - case ViewTypes.TOP: - // Setting divider visibilities - contactTile.setPaddingRelative(0, 0, - childIndex >= mColumnCount - 1 ? 0 : mPaddingInPixels, 0); - entryIndex = getFirstContactEntryIndexForPosition(mPosition) + childIndex; - break; - default: - break; - } - } - - @Override - protected void onLayout(boolean changed, int left, int top, int right, int bottom) { - switch (mItemViewType) { - case ViewTypes.TOP: - onLayoutForTiles(); - return; - default: - super.onLayout(changed, left, top, right, bottom); - return; - } - } - - private void onLayoutForTiles() { - final int count = getChildCount(); - - // Just line up children horizontally. - int childLeft = getPaddingStart(); - for (int i = 0; i < count; i++) { - final View child = getChildAt(i); - - // Note MeasuredWidth includes the padding. - final int childWidth = child.getMeasuredWidth(); - child.layout(childLeft, getPaddingTop(), childLeft + childWidth, - getPaddingTop() + child.getMeasuredHeight()); - childLeft += childWidth; - } - } - - @Override - protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { - switch (mItemViewType) { - case ViewTypes.TOP: - onMeasureForTiles(widthMeasureSpec); - return; - default: - super.onMeasure(widthMeasureSpec, heightMeasureSpec); - return; - } - } - - private void onMeasureForTiles(int widthMeasureSpec) { - final int width = MeasureSpec.getSize(widthMeasureSpec); - - final int childCount = getChildCount(); - if (childCount == 0) { - // Just in case... - setMeasuredDimension(width, 0); - return; - } - - // 1. Calculate image size. - // = ([total width] - [total padding]) / [child count] - // - // 2. Set it to width/height of each children. - // If we have a remainder, some tiles will have 1 pixel larger width than its height. - // - // 3. Set the dimensions of itself. - // Let width = given width. - // Let height = image size + bottom paddding. - - final int totalPaddingsInPixels = (mColumnCount - 1) * mPaddingInPixels - + mRowPaddingStart + mRowPaddingEnd; - - // Preferred width / height for images (excluding the padding). - // The actual width may be 1 pixel larger than this if we have a remainder. - final int imageWidth = (width - totalPaddingsInPixels) / mColumnCount; - final int remainder = width - (imageWidth * mColumnCount) - totalPaddingsInPixels; - - final int height = (int) (mHeightToWidthRatio * imageWidth); - - for (int i = 0; i < childCount; i++) { - final View child = getChildAt(i); - final int childWidth = imageWidth + child.getPaddingRight() - // Compensate for the remainder - + (i < remainder ? 1 : 0); - child.measure( - MeasureSpec.makeMeasureSpec(childWidth, MeasureSpec.EXACTLY), - MeasureSpec.makeMeasureSpec(height, MeasureSpec.EXACTLY) - ); - } - setMeasuredDimension(width, height); - } - - /** - * Gets the index of the item at the specified coordinates. - * - * @param itemX X-coordinate of the selected item. - * @param itemY Y-coordinate of the selected item. - * @return Index of the selected item in the cached array. - */ - public int getItemIndex(float itemX, float itemY) { - if (mMaxTiledRows == NO_ROW_LIMIT || mPosition < mMaxTiledRows) { - if (DEBUG) { - Log.v(TAG, String.valueOf(itemX) + " " + String.valueOf(itemY)); - } - for (int i = 0; i < getChildCount(); ++i) { - /** If the row contains multiple tiles, checks each tile to see if the point - * is contained in the tile. */ - final View child = getChildAt(i); - /** The coordinates passed in are based on the ListView, - * translate for each child first */ - final int xInListView = child.getLeft() + getLeft(); - final int yInListView = child.getTop() + getTop(); - final int distanceX = (int) itemX - xInListView; - final int distanceY = (int) itemY - yInListView; - if ((distanceX > 0 && distanceX < child.getWidth()) && - (distanceY > 0 && distanceY < child.getHeight())) { - /** If the point is contained in the rectangle, computes the index of the - * item in the cached array. */ - return i + (mPosition) * mColumnCount; - } - } - } else { - /** If the selected item is one of the rows, compute the index. */ - return getRegularRowItemIndex(); - } - return -1; - } - - /** - * Gets the index of the regular row item. - * - * @return Index of the selected item in the cached array. - */ - public int getRegularRowItemIndex() { - return (mPosition - mMaxTiledRows) + mColumnCount * mMaxTiledRows; - } - - public PhoneFavoritesTileAdapter getTileAdapter() { - return PhoneFavoritesTileAdapter.this; - } - - public int getPosition() { - return mPosition; - } - - /** - * Find the view under the pointer. - */ - public View getViewAtPosition(int x, int y) { - // find the view under the pointer, accounting for GONE views - final int count = getChildCount(); - View view; - for (int childIdx = 0; childIdx < count; childIdx++) { - view = getChildAt(childIdx); - if (x >= view.getLeft() && x <= view.getRight()) { - return view; - } - } - return null; - } - - public int getItemViewType() { - return mItemViewType; - } - } - - /** - * Used when a contact is swiped away. This will both unstar and set pinned position of the - * contact to PinnedPosition.DEMOTED so that it doesn't show up anymore in the favorites list. + * Used when a contact is removed from speeddial. This will both unstar and set pinned position + * of the contact to PinnedPosition.DEMOTED so that it doesn't show up anymore in the favorites + * list. */ private void unstarAndUnpinContact(Uri contactUri) { final ContentValues values = new ContentValues(2); @@ -1001,18 +603,25 @@ public class PhoneFavoritesTileAdapter extends BaseAdapter implements } protected static class ViewTypes { - public static final int TOP = 0; + public static final int TILE = 0; public static final int COUNT = 1; } @Override - public void onDragStarted(int itemIndex, int x, int y, PhoneFavoriteTileView view) { + public void onDragStarted(int x, int y, PhoneFavoriteSquareTileView view) { setInDragging(true); + final int itemIndex = mContactEntries.indexOf(view.getContactEntry()); popContactEntry(itemIndex); } @Override - public void onDragHovered(int itemIndex, int x, int y) { + public void onDragHovered(int x, int y, PhoneFavoriteSquareTileView view) { + if (view == null) { + // The user is hovering over a view that is not a contact tile, no need to do + // anything here. + return; + } + final int itemIndex = mContactEntries.indexOf(view.getContactEntry()); if (mInDragging && mDragEnteredEntryIndex != itemIndex && isIndexInBound(itemIndex) && -- cgit v1.2.3