diff options
author | Yorke Lee <yorkelee@google.com> | 2014-04-21 23:31:59 +0000 |
---|---|---|
committer | Android (Google) Code Review <android-gerrit@google.com> | 2014-04-21 23:31:59 +0000 |
commit | 4b10dd4a659bec13d5415fcaf24d2b60453f4d7a (patch) | |
tree | 7b1aacda1e3b2b611e9db89aaf5253646c3dc6eb /src | |
parent | 53845dc94a78d3efe4f8ea76a5e9a60dbc79aa16 (diff) | |
parent | efb2d9c2e32ca4ed434ff785c4b3d18c9e08db6d (diff) |
Merge "Use PhoneFavoritesTileAdapter directly in GridView"
Diffstat (limited to 'src')
9 files changed, 125 insertions, 633 deletions
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<ContactEntry>) - 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<ContactEntry> 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<ContactEntry> list, - long[] idsInPlace, int currentRow) { - if (mItemIdLeftMap.isEmpty()) { - return; - } - final AnimatorSet animSet = new AnimatorSet(); - final ArrayList<Animator> animators = new ArrayList<Animator>(); - 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<ContactEntry>) 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(); @@ -108,11 +101,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<ContactEntry>(); - // 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(); } } @@ -337,17 +313,6 @@ public class PhoneFavoritesTileAdapter extends BaseAdapter implements } /** - * 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. */ public int getNumFrequents() { @@ -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<ContactEntry> getItem(int position) { - ArrayList<ContactEntry> resultList = new ArrayList<ContactEntry>(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<ContactEntry> 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<ContactEntry> 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) && |