diff options
author | Hongwei Wang <hwwang@google.com> | 2013-09-13 17:56:05 -0700 |
---|---|---|
committer | Hongwei Wang <hwwang@google.com> | 2013-09-13 18:13:42 -0700 |
commit | 7639fe9a3ecc9c197718a9f81d8a745d2f660cb3 (patch) | |
tree | 0afea81d6a40a1a3ad4a1ef25aa761cec5c8664c /src | |
parent | 52f52702dac55c0fde27d907ac9ebb21fc707c68 (diff) |
Refactor the D-N-D, let list view handle all the events
Bug: 10686781
By moving the Drag and Drop logic to the list view, it helps
- Making the code more readable
- Making it feasible to control the drag shadow and animating more
easily
Change-Id: Ia30ea2d9379c1823ff056360fdcb8faadca553e8
Diffstat (limited to 'src')
7 files changed, 90 insertions, 196 deletions
diff --git a/src/com/android/dialer/list/PhoneFavoriteDragAndDropListeners.java b/src/com/android/dialer/list/PhoneFavoriteDragAndDropListeners.java deleted file mode 100644 index f0e97ac0b..000000000 --- a/src/com/android/dialer/list/PhoneFavoriteDragAndDropListeners.java +++ /dev/null @@ -1,132 +0,0 @@ -/* - * Copyright (C) 2013 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.android.dialer.list; - -import android.graphics.Rect; -import android.util.Log; -import android.view.DragEvent; -import android.view.View; -import android.view.View.OnDragListener; - -import com.android.dialer.list.PhoneFavoritesTileAdapter.ContactTileRow; - -/** - * Implements the OnLongClickListener and OnDragListener for phone's favorite tiles and rows. - */ -public class PhoneFavoriteDragAndDropListeners { - - private static final String TAG = PhoneFavoriteDragAndDropListeners.class.getSimpleName(); - private static final boolean DEBUG = false; - - /** - * Implements the OnDragListener to handle drag events. - */ - public static class PhoneFavoriteDragListener implements OnDragListener { - /** Location of the drag event. */ - private float mX = 0; - private float mY = 0; - private final ContactTileRow mContactTileRow; - private final PhoneFavoritesTileAdapter mTileAdapter; - - public PhoneFavoriteDragListener(ContactTileRow contactTileRow, - PhoneFavoritesTileAdapter tileAdapter) { - super(); - mContactTileRow = contactTileRow; - mTileAdapter = tileAdapter; - } - - /** - * @return The item index in {@link #mTileAdapter} for the given {@link DragEvent}. - * Returns -1 if {@link #mTileAdapter} is not in dragging or index can not be found. - */ - private int getDragItemIndex(DragEvent event) { - int itemIndex = -1; - if (mTileAdapter != null && mContactTileRow != null - && !mTileAdapter.getInDragging()) { - mX = event.getX(); - mY = event.getY(); - if (DEBUG) { - Log.v(TAG, String.valueOf(mX) + "; " + String.valueOf(mY)); - } - - final int[] rowLocation = new int[2]; - mContactTileRow.getLocationOnScreen(rowLocation); - - final Rect locationRect = new Rect(rowLocation[0], rowLocation[1], - rowLocation[0] + mContactTileRow.getWidth(), - rowLocation[1] + mContactTileRow.getHeight()); - - if (locationRect.contains((int) mX, (int) mY)) { - // Finds out which item is being dragged. - // Computes relative coordinates as we get absolute coordinates. - itemIndex = mContactTileRow.getItemIndex( - mX - rowLocation[0], mY - rowLocation[1]); - if (DEBUG) { - Log.v(TAG, "Start dragging " + String.valueOf(itemIndex)); - } - } - } - return itemIndex; - } - - @Override - public boolean onDrag(View v, DragEvent event) { - if (DEBUG) { - Log.v(TAG, event.toString()); - } - // Handles drag events. - switch (event.getAction()) { - case DragEvent.ACTION_DRAG_STARTED: - final int itemIndex = getDragItemIndex(event); - if (itemIndex != -1) { - // Indicates a drag has started. - mTileAdapter.setInDragging(true); - - // Temporarily pops out the Contact entry. - mTileAdapter.popContactEntry(itemIndex); - } - break; - case DragEvent.ACTION_DRAG_ENTERED: - break; - case DragEvent.ACTION_DRAG_EXITED: - break; - case DragEvent.ACTION_DROP: - // Indicates a drag has finished. - if (mTileAdapter != null && mContactTileRow != null) { - mTileAdapter.setInDragging(false); - // The drop to position has been reported to the adapter - // via {@link DragEvent#ACTION_DRAG_LOCATION} events in ListView. - mTileAdapter.handleDrop(); - } - break; - case DragEvent.ACTION_DRAG_ENDED: - if (mTileAdapter != null && mTileAdapter.getInDragging()) { - // If the drag and drop ends when the drop happens outside of any rows, - // we will end the drag here and put the item back to where it was dragged - // from before. - mTileAdapter.setInDragging(false); - mTileAdapter.handleDrop(); - } - break; - case DragEvent.ACTION_DRAG_LOCATION: - break; - default: - break; - } - return true; - } - } -} diff --git a/src/com/android/dialer/list/PhoneFavoriteFragment.java b/src/com/android/dialer/list/PhoneFavoriteFragment.java index 270ed6312..d8179e797 100644 --- a/src/com/android/dialer/list/PhoneFavoriteFragment.java +++ b/src/com/android/dialer/list/PhoneFavoriteFragment.java @@ -211,6 +211,7 @@ public class PhoneFavoriteFragment extends Fragment implements OnItemClickListen mListView.setVerticalScrollbarPosition(View.SCROLLBAR_POSITION_RIGHT); mListView.setScrollBarStyle(ListView.SCROLLBARS_OUTSIDE_OVERLAY); mListView.setOnItemSwipeListener(mContactTileAdapter); + mListView.setOnDragDropListener(mContactTileAdapter); mEmptyView = inflater.inflate(R.layout.phone_no_favorites, mListView, false); diff --git a/src/com/android/dialer/list/PhoneFavoriteListView.java b/src/com/android/dialer/list/PhoneFavoriteListView.java index 00f645ab0..4636e1794 100644 --- a/src/com/android/dialer/list/PhoneFavoriteListView.java +++ b/src/com/android/dialer/list/PhoneFavoriteListView.java @@ -47,6 +47,7 @@ public class PhoneFavoriteListView extends ListView implements SwipeHelperCallba private boolean mEnableSwipe = true; private OnItemGestureListener mOnItemGestureListener; + private OnDragDropListener mOnDragDropListener; private float mDensityScale; private float mTouchSlop; @@ -60,6 +61,7 @@ public class PhoneFavoriteListView extends ListView implements SwipeHelperCallba private final int DRAG_SCROLL_PX_UNIT = 10; private boolean mIsDragScrollerRunning = false; + private int mTouchDownForDragStartX; private int mTouchDownForDragStartY; /** @@ -121,9 +123,14 @@ public class PhoneFavoriteListView extends ListView implements SwipeHelperCallba mOnItemGestureListener = listener; } + public void setOnDragDropListener(OnDragDropListener listener) { + mOnDragDropListener = listener; + } + @Override public boolean onInterceptTouchEvent(MotionEvent ev) { if (ev.getAction() == MotionEvent.ACTION_DOWN) { + mTouchDownForDragStartX = (int) ev.getX(); mTouchDownForDragStartY = (int) ev.getY(); } if (isSwipeEnabled()) { @@ -147,24 +154,13 @@ public class PhoneFavoriteListView extends ListView implements SwipeHelperCallba @Override public View getChildAtPosition(MotionEvent ev) { - // find the view under the pointer, accounting for GONE views - final int count = getChildCount(); - final int touchY = (int) ev.getY(); - View slidingChild; - for (int childIdx = 0; childIdx < count; childIdx++) { - slidingChild = getChildAt(childIdx); - if (slidingChild.getVisibility() == GONE) { - continue; - } - if (touchY >= slidingChild.getTop() && touchY <= slidingChild.getBottom()) { - if (SwipeHelper.isSwipeable(slidingChild)) { - // If this view is swipable in this listview, then return it. Otherwise - // return a null view, which will simply be ignored by the swipe helper. - return slidingChild; - } else { - return null; - } - } + final View view = getViewAtPosition((int) ev.getX(), (int) ev.getY()); + if (view != null && + SwipeHelper.isSwipeable(view) && + view.getVisibility() != GONE) { + // If this view is swipable in this listview, then return it. Otherwise + // return a null view, which will simply be ignored by the swipe helper. + return view; } return null; } @@ -205,10 +201,16 @@ public class PhoneFavoriteListView extends ListView implements SwipeHelperCallba @Override public boolean dispatchDragEvent(DragEvent event) { - switch (event.getAction()) { + final int action = event.getAction(); + final int eX = (int) event.getX(); + final int eY = (int) event.getY(); + switch (action) { + case DragEvent.ACTION_DRAG_STARTED: + handleDragStarted(mTouchDownForDragStartX, mTouchDownForDragStartY); + break; case DragEvent.ACTION_DRAG_LOCATION: - mLastDragY = (int) event.getY(); - handleDrag((int) event.getX(), mLastDragY); + mLastDragY = eY; + handleDragHovered(eX, eY); // Kick off {@link #mScrollHandler} if it's not started yet. if (!mIsDragScrollerRunning && // And if the distance traveled while dragging exceeds the touch slop @@ -229,13 +231,30 @@ public class PhoneFavoriteListView extends ListView implements SwipeHelperCallba ensureScrollHandler(); mScrollHandler.removeCallbacks(mDragScroller); mIsDragScrollerRunning = false; + if (action != DragEvent.ACTION_DRAG_EXITED) { + handleDragFinished(); + } break; - case DragEvent.ACTION_DRAG_STARTED: - // Not a receiver default: break; } - return super.dispatchDragEvent(event); + // This ListView will consumer the drag events on behalf of its children. + return true; + } + + /** + * Find the view under the pointer. + */ + private View getViewAtPosition(int x, int y) { + final int count = getChildCount(); + View child; + for (int childIdx = 0; childIdx < count; childIdx++) { + child = getChildAt(childIdx); + if (y >= child.getTop() && y <= child.getBottom()) { + return child; + } + } + return null; } private void ensureScrollHandler() { @@ -244,29 +263,37 @@ public class PhoneFavoriteListView extends ListView implements SwipeHelperCallba } } - private void handleDrag(int x, int y) { - // find the view under the pointer, accounting for GONE views - final int count = getChildCount(); - View slidingChild; - for (int childIdx = 0; childIdx < count; childIdx++) { - slidingChild = getChildAt(childIdx); - if (slidingChild.getVisibility() == GONE) { - continue; + private void handleDragStarted(int x, int y) { + final View child = getViewAtPosition(x, y); + if (child instanceof ContactTileRow) { + final ContactTileRow tile = (ContactTileRow) child; + final int itemIndex = tile.getItemIndex(x, y); + if (itemIndex != -1 && mOnDragDropListener != null) { + mOnDragDropListener.onDragStarted(itemIndex); } - if (y >= slidingChild.getTop() && - y <= slidingChild.getBottom() && - slidingChild instanceof ContactTileRow) { - final ContactTileRow tile = (ContactTileRow) slidingChild; - reportDragEnteredItemIndex(tile.getItemIndex(x, y)); + } + } + + private void handleDragHovered(int x, int y) { + final View child = getViewAtPosition(x, y); + if (child instanceof ContactTileRow) { + final ContactTileRow tile = (ContactTileRow) child; + final int itemIndex = tile.getItemIndex(x, y); + if (itemIndex != -1 && mOnDragDropListener != null) { + mOnDragDropListener.onDragHovered(itemIndex); } } } - private void reportDragEnteredItemIndex(int itemIndex) { - final PhoneFavoriteMergedAdapter adapter = - (PhoneFavoriteMergedAdapter) getAdapter(); - if (adapter != null) { - adapter.reportDragEnteredItemIndex(itemIndex); + private void handleDragFinished() { + if (mOnDragDropListener != null) { + mOnDragDropListener.onDragFinished(); } } + + public interface OnDragDropListener { + public void onDragStarted(int itemIndex); + public void onDragHovered(int itemIndex); + public void onDragFinished(); + } } diff --git a/src/com/android/dialer/list/PhoneFavoriteMergedAdapter.java b/src/com/android/dialer/list/PhoneFavoriteMergedAdapter.java index 084a34e98..c7554e212 100644 --- a/src/com/android/dialer/list/PhoneFavoriteMergedAdapter.java +++ b/src/com/android/dialer/list/PhoneFavoriteMergedAdapter.java @@ -346,10 +346,4 @@ public class PhoneFavoriteMergedAdapter extends BaseAdapter { mOnItemSwipeListener = listener; } } - - public void reportDragEnteredItemIndex(int itemIndex) { - if (mContactTileAdapter != null) { - mContactTileAdapter.reportDragEnteredItemIndex(itemIndex); - } - } } diff --git a/src/com/android/dialer/list/PhoneFavoriteRegularRowView.java b/src/com/android/dialer/list/PhoneFavoriteRegularRowView.java index 374f733ec..efe7bdd7f 100644 --- a/src/com/android/dialer/list/PhoneFavoriteRegularRowView.java +++ b/src/com/android/dialer/list/PhoneFavoriteRegularRowView.java @@ -23,7 +23,6 @@ import android.view.View; import com.android.contacts.common.util.ViewUtil; import com.android.dialer.R; -import com.android.dialer.list.PhoneFavoriteDragAndDropListeners.PhoneFavoriteDragListener; import com.android.dialer.list.PhoneFavoritesTileAdapter.ContactTileRow; diff --git a/src/com/android/dialer/list/PhoneFavoriteTileView.java b/src/com/android/dialer/list/PhoneFavoriteTileView.java index 76a0e352b..374ff874c 100644 --- a/src/com/android/dialer/list/PhoneFavoriteTileView.java +++ b/src/com/android/dialer/list/PhoneFavoriteTileView.java @@ -20,7 +20,6 @@ import android.animation.Animator; import android.animation.AnimatorListenerAdapter; import android.animation.AnimatorSet; import android.animation.ObjectAnimator; -import android.content.ClipData; import android.content.Context; import android.text.TextUtils; import android.util.AttributeSet; @@ -32,7 +31,6 @@ import android.view.View; import com.android.contacts.common.MoreContactUtils; import com.android.contacts.common.list.ContactEntry; import com.android.contacts.common.list.ContactTileView; -import com.android.dialer.list.PhoneFavoriteDragAndDropListeners.PhoneFavoriteDragListener; import com.android.dialer.list.PhoneFavoritesTileAdapter.ContactTileRow; import com.android.dialer.list.PhoneFavoritesTileAdapter.ViewTypes; @@ -94,20 +92,16 @@ public abstract class PhoneFavoriteTileView extends ContactTileView { public boolean onLongClick(View v) { setPressed(false); final PhoneFavoriteTileView view = (PhoneFavoriteTileView) v; - final ClipData data = ClipData.newPlainText("", ""); if (view instanceof PhoneFavoriteRegularRowView) { - // If the view is regular row, start drag the row view. - final View.DragShadowBuilder shadowBuilder = - new View.DragShadowBuilder(view.getParentRow()); final ContactTileRow parent = (ContactTileRow) view.getParentRow(); + // If the view is regular row, start drag the row view. // Drag is not available for the item exceeds the PIN_LIMIT. if (parent.getRegularRowItemIndex() < PhoneFavoritesTileAdapter.PIN_LIMIT) { - view.getParentRow().startDrag(data, shadowBuilder, null, 0); + parent.startDrag(null, new View.DragShadowBuilder(parent), null, 0); } } else { // If the view is a tile view, start drag the tile. - final View.DragShadowBuilder shadowBuilder = new View.DragShadowBuilder(view); - view.startDrag(data, shadowBuilder, null, 0); + view.startDrag(null, new View.DragShadowBuilder(view), null, 0); } return true; } @@ -205,8 +199,6 @@ public abstract class PhoneFavoriteTileView extends ContactTileView { @Override protected void onAttachedToWindow() { mParentRow = (ContactTileRow) getParent(); - mParentRow.setOnDragListener(new PhoneFavoriteDragListener(mParentRow, - mParentRow.getTileAdapter())); } @Override diff --git a/src/com/android/dialer/list/PhoneFavoritesTileAdapter.java b/src/com/android/dialer/list/PhoneFavoritesTileAdapter.java index 4eaeaf51a..8d0fb8647 100644 --- a/src/com/android/dialer/list/PhoneFavoritesTileAdapter.java +++ b/src/com/android/dialer/list/PhoneFavoritesTileAdapter.java @@ -62,7 +62,7 @@ import java.util.PriorityQueue; * */ public class PhoneFavoritesTileAdapter extends BaseAdapter implements - SwipeHelper.OnItemGestureListener { + SwipeHelper.OnItemGestureListener, PhoneFavoriteListView.OnDragDropListener { private static final String TAG = PhoneFavoritesTileAdapter.class.getSimpleName(); private static final boolean DEBUG = false; @@ -1192,11 +1192,14 @@ public class PhoneFavoritesTileAdapter extends BaseAdapter implements return !mAwaitingRemove; } - public void setEmptyView(View emptyView) { - mEmptyView = emptyView; + @Override + public void onDragStarted(int itemIndex) { + setInDragging(true); + popContactEntry(itemIndex); } - public void reportDragEnteredItemIndex(int itemIndex) { + @Override + public void onDragHovered(int itemIndex) { if (mInDragging && mDragEnteredEntryIndex != itemIndex && isIndexInBound(itemIndex) && @@ -1204,4 +1207,14 @@ public class PhoneFavoritesTileAdapter extends BaseAdapter implements markDropArea(itemIndex); } } + + @Override + public void onDragFinished() { + setInDragging(false); + handleDrop(); + } + + public void setEmptyView(View emptyView) { + mEmptyView = emptyView; + } } |