diff options
author | Yorke Lee <yorkelee@google.com> | 2014-05-01 10:05:52 -0700 |
---|---|---|
committer | Yorke Lee <yorkelee@google.com> | 2014-05-06 18:57:15 -0700 |
commit | 2826619b274772beebc7369d5dfe616344f74b6f (patch) | |
tree | 74fece83bea0449bb1bab2397d07eb19aab81b7d /src | |
parent | 3d3ff68ffb5f0f30e03d4456892cf3e1912e39d4 (diff) |
Refactor drag and drop to work for entire Dialer layout
Add a drag listener to the main dialer layout and manipulate
drag events correctly in DragDropController so that drag and
drop works throughout the main Dialer layout, rather than just the
speed dial fragment.
Also shift the remove view into dialtacts_mainlayout so that it can
continue receiving drag events.
Bug: 14393052
Change-Id: I90c26fee4fe681d0e237aa490185e850628e4cd0
Diffstat (limited to 'src')
-rw-r--r-- | src/com/android/dialer/DialtactsActivity.java | 47 | ||||
-rw-r--r-- | src/com/android/dialer/list/DragDropController.java | 40 | ||||
-rw-r--r-- | src/com/android/dialer/list/PhoneFavoriteListView.java | 48 | ||||
-rw-r--r-- | src/com/android/dialer/list/RemoveView.java | 53 |
4 files changed, 112 insertions, 76 deletions
diff --git a/src/com/android/dialer/DialtactsActivity.java b/src/com/android/dialer/DialtactsActivity.java index ce7124531..b96553074 100644 --- a/src/com/android/dialer/DialtactsActivity.java +++ b/src/com/android/dialer/DialtactsActivity.java @@ -44,10 +44,12 @@ import android.text.Editable; import android.text.TextUtils; import android.text.TextWatcher; import android.util.Log; +import android.view.DragEvent; import android.view.Menu; import android.view.MenuInflater; import android.view.MenuItem; import android.view.View; +import android.view.View.OnDragListener; import android.view.animation.AccelerateInterpolator; import android.view.animation.DecelerateInterpolator; import android.view.animation.Interpolator; @@ -56,7 +58,6 @@ import android.widget.AbsListView.OnScrollListener; import android.widget.EditText; import android.widget.PopupMenu; import android.widget.RelativeLayout; -import android.widget.SearchView; import android.widget.Toast; import com.android.contacts.common.CallUtil; @@ -185,9 +186,6 @@ public class DialtactsActivity extends TransactionSafeActivity implements View.O */ private String mPendingSearchViewQuery; - // This view points to the Framelayout that houses both the search view and remove view - // containers. - private View mSearchAndRemoveViewContainer; private EditText mSearchView; private View mSearchViewCloseButton; private View mVoiceSearchButton; @@ -196,13 +194,14 @@ public class DialtactsActivity extends TransactionSafeActivity implements View.O * If the user releases a contact when hovering on top of this, the contact is unfavorited and * removed from the speed dial list. */ - private RemoveView mRemoveViewContainer; + private View mRemoveViewContainer; final Interpolator hideActionBarInterpolator = new AccelerateInterpolator(1.5f); final Interpolator showActionBarInterpolator = new DecelerateInterpolator(1.5f); private String mSearchQuery; private DialerDatabaseHelper mDialerDatabaseHelper; + private DragDropController mDragDropController; private class OverflowPopupMenu extends PopupMenu { public OverflowPopupMenu(Context context, View anchor) { @@ -220,6 +219,21 @@ public class DialtactsActivity extends TransactionSafeActivity implements View.O } /** + * Listener that listens to drag events and sends their x and y coordinates to a + * {@link DragDropController}. + */ + private class LayoutOnDragListener implements OnDragListener { + @Override + public boolean onDrag(View v, DragEvent event) { + if (event.getAction() == DragEvent.ACTION_DRAG_LOCATION) { + mDragDropController.handleDragHovered(v, (int) event.getX(), + (int) event.getY()); + } + return true; + } + } + + /** * Listener used when one of phone numbers in search UI is selected. This will initiate a * phone call using the phone number. */ @@ -363,11 +377,12 @@ public class DialtactsActivity extends TransactionSafeActivity implements View.O mDialpadButton = findViewById(R.id.dialpad_button); mDialpadButton.setOnClickListener(this); - mRemoveViewContainer = (RemoveView) findViewById(R.id.remove_view_container); - mSearchAndRemoveViewContainer = findViewById(R.id.search_and_remove_view_container); + mRemoveViewContainer = findViewById(R.id.remove_view_container); mDialerDatabaseHelper = DatabaseHelperManager.getDatabaseHelper(this); SmartDialPrefix.initializeNanpSettings(this); + + findViewById(R.id.dialtacts_mainlayout).setOnDragListener(new LayoutOnDragListener()); } @Override @@ -574,13 +589,6 @@ public class DialtactsActivity extends TransactionSafeActivity implements View.O ft.commit(); } - final AnimatorListener mHideListener = new AnimatorListenerAdapter() { - @Override - public void onAnimationEnd(Animator animation) { - mSearchAndRemoveViewContainer.setVisibility(View.GONE); - } - }; - private boolean getInSearchUi() { return mInDialpadSearch || mInRegularSearch; } @@ -936,11 +944,12 @@ public class DialtactsActivity extends TransactionSafeActivity implements View.O @Override public void onDragStarted(int x, int y, PhoneFavoriteSquareTileView view) { getActionBar().hide(); - mSearchAndRemoveViewContainer.setVisibility(View.VISIBLE); + mRemoveViewContainer.setVisibility(View.VISIBLE); } @Override - public void onDragHovered(int x, int y, PhoneFavoriteSquareTileView view) {} + public void onDragHovered(int x, int y, PhoneFavoriteSquareTileView view) { + } /** * Called when the user has released a contact tile after long-pressing it. @@ -948,7 +957,7 @@ public class DialtactsActivity extends TransactionSafeActivity implements View.O @Override public void onDragFinished(int x, int y) { getActionBar().show(); - mSearchAndRemoveViewContainer.setVisibility(View.GONE); + mRemoveViewContainer.setVisibility(View.GONE); } @Override @@ -960,7 +969,9 @@ public class DialtactsActivity extends TransactionSafeActivity implements View.O */ @Override public void setDragDropController(DragDropController dragController) { - mRemoveViewContainer.setDragDropController(dragController); + mDragDropController = dragController; + ((RemoveView) findViewById(R.id.remove_view)) + .setDragDropController(dragController); } @Override diff --git a/src/com/android/dialer/list/DragDropController.java b/src/com/android/dialer/list/DragDropController.java index db4dd5937..8cd1046e6 100644 --- a/src/com/android/dialer/list/DragDropController.java +++ b/src/com/android/dialer/list/DragDropController.java @@ -1,5 +1,8 @@ package com.android.dialer.list; +import android.util.Log; +import android.view.View; + import java.util.ArrayList; import java.util.List; @@ -8,27 +11,48 @@ import java.util.List; * off events to any OnDragDropListeners that have registered for callbacks. */ public class DragDropController { - private List<OnDragDropListener> mOnDragDropListeners = new ArrayList<OnDragDropListener>(); + + private final List<OnDragDropListener> mOnDragDropListeners = + new ArrayList<OnDragDropListener>(); + private final DragItemContainer mDragItemContainer; + private final int[] mLocationOnScreen = new int[2]; + + /** + * Callback interface used to retrieve views based on the current touch coordinates of the + * drag event. The {@link DragItemContainer} houses the draggable views that this + * {@link DragDropController} controls. + */ + public interface DragItemContainer { + public PhoneFavoriteSquareTileView getViewForLocation(int x, int y); + } + + public DragDropController(DragItemContainer dragItemContainer) { + mDragItemContainer = dragItemContainer; + } /** * @return True if the drag is started, false if the drag is cancelled for some reason. */ - boolean handleDragStarted(int x, int y, PhoneFavoriteSquareTileView tileView) { + boolean handleDragStarted(int x, int y) { + final PhoneFavoriteSquareTileView tileView = mDragItemContainer.getViewForLocation(x, y); if (tileView == null) { return false; } - if (tileView != null && !mOnDragDropListeners.isEmpty()) { - for (int i = 0; i < mOnDragDropListeners.size(); i++) { - mOnDragDropListeners.get(i).onDragStarted(x, y, tileView); - } + for (int i = 0; i < mOnDragDropListeners.size(); i++) { + mOnDragDropListeners.get(i).onDragStarted(x, y, tileView); } return true; } - public void handleDragHovered(int x, int y, PhoneFavoriteSquareTileView view) { + public void handleDragHovered(View v, int x, int y) { + v.getLocationOnScreen(mLocationOnScreen); + final int screenX = x + mLocationOnScreen[0]; + final int screenY = y + mLocationOnScreen[1]; + final PhoneFavoriteSquareTileView view = mDragItemContainer.getViewForLocation( + screenX, screenY); for (int i = 0; i < mOnDragDropListeners.size(); i++) { - mOnDragDropListeners.get(i).onDragHovered(x, y, view); + mOnDragDropListeners.get(i).onDragHovered(screenX, screenY, view); } } diff --git a/src/com/android/dialer/list/PhoneFavoriteListView.java b/src/com/android/dialer/list/PhoneFavoriteListView.java index 6c3d62a59..074cc07d6 100644 --- a/src/com/android/dialer/list/PhoneFavoriteListView.java +++ b/src/com/android/dialer/list/PhoneFavoriteListView.java @@ -33,11 +33,13 @@ import android.widget.GridView; import android.widget.ImageView; import com.android.dialer.R; +import com.android.dialer.list.DragDropController.DragItemContainer; /** * Viewgroup that presents the user's speed dial contacts in a grid. */ -public class PhoneFavoriteListView extends GridView implements OnDragDropListener { +public class PhoneFavoriteListView extends GridView implements OnDragDropListener, + DragItemContainer { public static final String LOG_TAG = PhoneFavoriteListView.class.getSimpleName(); @@ -59,6 +61,8 @@ public class PhoneFavoriteListView extends GridView implements OnDragDropListene private ImageView mDragShadowOverlay; private int mAnimationDuration; + final int[] mLocationOnScreen = new int[2]; + // X and Y offsets inside the item from where the user grabbed to the // child's left coordinate. This is used to aid in the drawing of the drag shadow. private int mTouchOffsetToChildLeft; @@ -67,7 +71,7 @@ public class PhoneFavoriteListView extends GridView implements OnDragDropListene private int mDragShadowLeft; private int mDragShadowTop; - private DragDropController mDragDropController = new DragDropController(); + private DragDropController mDragDropController = new DragDropController(this); private final float DRAG_SHADOW_ALPHA = 0.7f; @@ -138,39 +142,20 @@ public class PhoneFavoriteListView extends GridView implements OnDragDropListene } @Override - public boolean dispatchDragEvent(DragEvent event) { + public boolean onDragEvent(DragEvent event) { final int action = event.getAction(); final int eX = (int) event.getX(); final int eY = (int) event.getY(); switch (action) { 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 - final int viewX = eX - coordinates[0]; - final int viewY = eY - coordinates[1]; - final View child = getViewAtPosition(viewX, viewY); - - if (!(child instanceof PhoneFavoriteSquareTileView)) { - // Bail early. - return false; - } - - final PhoneFavoriteSquareTileView tile = (PhoneFavoriteSquareTileView) child; - if (!mDragDropController.handleDragStarted(viewX, viewY, tile)) { + if (!mDragDropController.handleDragStarted(eX, eY)) { return false; } break; } case DragEvent.ACTION_DRAG_LOCATION: mLastDragY = eY; - final View child = getViewAtPosition(eX, eY); - - PhoneFavoriteSquareTileView tile = null; - if (child instanceof PhoneFavoriteSquareTileView) { - tile = (PhoneFavoriteSquareTileView) child; - } - mDragDropController.handleDragHovered(eX, eY, tile); + mDragDropController.handleDragHovered(this, 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 @@ -313,4 +298,19 @@ public class PhoneFavoriteListView extends GridView implements OnDragDropListene return bitmap; } + + @Override + public PhoneFavoriteSquareTileView getViewForLocation(int x, int y) { + getLocationOnScreen(mLocationOnScreen); + // Calculate the X and Y coordinates of the drag event relative to the view + final int viewX = x - mLocationOnScreen[0]; + final int viewY = y - mLocationOnScreen[1]; + final View child = getViewAtPosition(viewX, viewY); + + if (!(child instanceof PhoneFavoriteSquareTileView)) { + return null; + } + + return (PhoneFavoriteSquareTileView) child; + } } diff --git a/src/com/android/dialer/list/RemoveView.java b/src/com/android/dialer/list/RemoveView.java index 16942fe96..ae358fc9f 100644 --- a/src/com/android/dialer/list/RemoveView.java +++ b/src/com/android/dialer/list/RemoveView.java @@ -4,14 +4,16 @@ import android.content.Context; import android.content.res.Resources; import android.graphics.drawable.Drawable; import android.util.AttributeSet; +import android.util.Log; import android.view.DragEvent; +import android.widget.FrameLayout; import android.widget.ImageView; import android.widget.LinearLayout; import android.widget.TextView; import com.android.dialer.R; -public class RemoveView extends LinearLayout { +public class RemoveView extends FrameLayout { DragDropController mDragDropController; TextView mRemoveText; @@ -49,31 +51,30 @@ public class RemoveView extends LinearLayout { } @Override - public boolean dispatchDragEvent(DragEvent event) { - final int action = event.getAction(); - switch (action) { - case DragEvent.ACTION_DRAG_ENTERED: - setAppearanceHighlighted(); - break; - case DragEvent.ACTION_DRAG_EXITED: - setAppearanceNormal(); - break; - case DragEvent.ACTION_DRAG_LOCATION: - if (mDragDropController != null) { - mDragDropController.handleDragHovered((int) event.getX(), - // the true y-coordinate of the event with respect to the listview is - // offset by the height of the remove view - (int) event.getY() - getHeight(), null); - } - break; - case DragEvent.ACTION_DROP: - if (mDragDropController != null) { - mDragDropController.handleDragFinished((int) event.getX(), (int) event.getY(), true); - } - setAppearanceNormal(); - break; - } - return true; + public boolean onDragEvent(DragEvent event) { + final int action = event.getAction(); + switch (action) { + case DragEvent.ACTION_DRAG_ENTERED: + setAppearanceHighlighted(); + break; + case DragEvent.ACTION_DRAG_EXITED: + setAppearanceNormal(); + break; + case DragEvent.ACTION_DRAG_LOCATION: + if (mDragDropController != null) { + mDragDropController.handleDragHovered(this, (int) event.getX(), + (int) event.getY()); + } + break; + case DragEvent.ACTION_DROP: + if (mDragDropController != null) { + mDragDropController.handleDragFinished((int) event.getX(), (int) event.getY(), + true); + } + setAppearanceNormal(); + break; + } + return true; } private void setAppearanceNormal() { |