summaryrefslogtreecommitdiff
path: root/java/com/android/dialer/speeddial
diff options
context:
space:
mode:
authorcalderwoodra <calderwoodra@google.com>2018-04-13 14:58:17 -0700
committerCopybara-Service <copybara-piper@google.com>2018-04-13 15:00:08 -0700
commit5621909c288e785ff9c8a6cc12d3dae8ed837b66 (patch)
treea59d481b856647dd26a0aefd0ea3be8e82784303 /java/com/android/dialer/speeddial
parent0d0afb36ac53cc58f2674d2571c8db6cd75d8cbb (diff)
Implement drag to remove contacts in SpeedDialFragment.
Bug: 36841782 Test: manual PiperOrigin-RevId: 192828773 Change-Id: Id9066346e6b2a03f672ce3ad11027f15adfbb7e6
Diffstat (limited to 'java/com/android/dialer/speeddial')
-rw-r--r--java/com/android/dialer/speeddial/ContextMenu.java4
-rw-r--r--java/com/android/dialer/speeddial/FavoritesViewHolder.java24
-rw-r--r--java/com/android/dialer/speeddial/SpeedDialAdapter.java76
-rw-r--r--java/com/android/dialer/speeddial/SpeedDialFragment.java41
-rw-r--r--java/com/android/dialer/speeddial/draghelper/SpeedDialFavoritesViewHolderOnTouchListener.java107
-rw-r--r--java/com/android/dialer/speeddial/draghelper/SpeedDialItemTouchHelperCallback.java83
-rw-r--r--java/com/android/dialer/speeddial/draghelper/SpeedDialLayoutManager.java40
7 files changed, 338 insertions, 37 deletions
diff --git a/java/com/android/dialer/speeddial/ContextMenu.java b/java/com/android/dialer/speeddial/ContextMenu.java
index a7fa65556..b6ac98862 100644
--- a/java/com/android/dialer/speeddial/ContextMenu.java
+++ b/java/com/android/dialer/speeddial/ContextMenu.java
@@ -81,6 +81,10 @@ public class ContextMenu extends LinearLayout {
}
}
+ public boolean isVisible() {
+ return getVisibility() == View.VISIBLE;
+ }
+
/** Listener to report user clicks on menu items. */
public interface ContextMenuItemListener {
diff --git a/java/com/android/dialer/speeddial/FavoritesViewHolder.java b/java/com/android/dialer/speeddial/FavoritesViewHolder.java
index 4f0cf65a0..56d9f36d9 100644
--- a/java/com/android/dialer/speeddial/FavoritesViewHolder.java
+++ b/java/com/android/dialer/speeddial/FavoritesViewHolder.java
@@ -19,9 +19,11 @@ package com.android.dialer.speeddial;
import android.content.Context;
import android.provider.ContactsContract.Contacts;
import android.support.v7.widget.RecyclerView;
+import android.support.v7.widget.helper.ItemTouchHelper;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.View.OnLongClickListener;
+import android.view.ViewConfiguration;
import android.widget.FrameLayout;
import android.widget.QuickContactBadge;
import android.widget.TextView;
@@ -29,12 +31,14 @@ import com.android.dialer.common.Assert;
import com.android.dialer.glidephotomanager.GlidePhotoManagerComponent;
import com.android.dialer.glidephotomanager.PhotoInfo;
import com.android.dialer.speeddial.database.SpeedDialEntry.Channel;
+import com.android.dialer.speeddial.draghelper.SpeedDialFavoritesViewHolderOnTouchListener;
+import com.android.dialer.speeddial.draghelper.SpeedDialFavoritesViewHolderOnTouchListener.OnTouchFinishCallback;
import com.android.dialer.speeddial.loader.SpeedDialUiItem;
import java.util.List;
/** ViewHolder for starred/favorite contacts in {@link SpeedDialFragment}. */
public class FavoritesViewHolder extends RecyclerView.ViewHolder
- implements OnClickListener, OnLongClickListener {
+ implements OnClickListener, OnLongClickListener, OnTouchFinishCallback {
private final FavoriteContactsListener listener;
@@ -45,7 +49,7 @@ public class FavoritesViewHolder extends RecyclerView.ViewHolder
private SpeedDialUiItem speedDialUiItem;
- public FavoritesViewHolder(View view, FavoriteContactsListener listener) {
+ public FavoritesViewHolder(View view, ItemTouchHelper helper, FavoriteContactsListener listener) {
super(view);
photoView = view.findViewById(R.id.avatar);
nameView = view.findViewById(R.id.name);
@@ -53,6 +57,9 @@ public class FavoritesViewHolder extends RecyclerView.ViewHolder
videoCallIcon = view.findViewById(R.id.video_call_container);
view.setOnClickListener(this);
view.setOnLongClickListener(this);
+ view.setOnTouchListener(
+ new SpeedDialFavoritesViewHolderOnTouchListener(
+ ViewConfiguration.get(view.getContext()), helper, this, this));
photoView.setClickable(false);
this.listener = listener;
}
@@ -96,12 +103,16 @@ public class FavoritesViewHolder extends RecyclerView.ViewHolder
@Override
public boolean onLongClick(View view) {
- // TODO(calderwoodra): implement drag and drop logic
// TODO(calderwoodra): add bounce/sin wave scale animation
- listener.onLongClick(photoView, speedDialUiItem);
+ listener.showContextMenu(photoView, speedDialUiItem);
return true;
}
+ @Override
+ public void onTouchFinished(boolean closeContextMenu) {
+ listener.onTouchFinished(closeContextMenu);
+ }
+
/** Listener/callback for {@link FavoritesViewHolder} actions. */
public interface FavoriteContactsListener {
@@ -112,6 +123,9 @@ public class FavoritesViewHolder extends RecyclerView.ViewHolder
void onClick(Channel channel);
/** Called when the user long clicks on a favorite contact. */
- void onLongClick(View view, SpeedDialUiItem speedDialUiItem);
+ void showContextMenu(View view, SpeedDialUiItem speedDialUiItem);
+
+ /** Called when the user is no longer touching the favorite contact. */
+ void onTouchFinished(boolean closeContextMenu);
}
}
diff --git a/java/com/android/dialer/speeddial/SpeedDialAdapter.java b/java/com/android/dialer/speeddial/SpeedDialAdapter.java
index 3312397c7..6f6ac5498 100644
--- a/java/com/android/dialer/speeddial/SpeedDialAdapter.java
+++ b/java/com/android/dialer/speeddial/SpeedDialAdapter.java
@@ -21,12 +21,10 @@ import android.content.Context;
import android.os.Build.VERSION_CODES;
import android.support.annotation.IntDef;
import android.support.annotation.NonNull;
-import android.support.annotation.VisibleForTesting;
-import android.support.v7.widget.GridLayoutManager;
import android.support.v7.widget.GridLayoutManager.SpanSizeLookup;
import android.support.v7.widget.RecyclerView;
-import android.support.v7.widget.RecyclerView.LayoutManager;
import android.support.v7.widget.RecyclerView.ViewHolder;
+import android.support.v7.widget.helper.ItemTouchHelper;
import android.util.ArrayMap;
import android.view.LayoutInflater;
import android.view.ViewGroup;
@@ -34,10 +32,12 @@ import com.android.dialer.common.Assert;
import com.android.dialer.speeddial.FavoritesViewHolder.FavoriteContactsListener;
import com.android.dialer.speeddial.HeaderViewHolder.SpeedDialHeaderListener;
import com.android.dialer.speeddial.SuggestionViewHolder.SuggestedContactsListener;
+import com.android.dialer.speeddial.draghelper.SpeedDialItemTouchHelperCallback.ItemTouchHelperAdapter;
import com.android.dialer.speeddial.loader.SpeedDialUiItem;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.util.ArrayList;
+import java.util.Collections;
import java.util.List;
import java.util.Map;
@@ -55,7 +55,8 @@ import java.util.Map;
*/
@SuppressWarnings("AndroidApiChecker")
@TargetApi(VERSION_CODES.N)
-public final class SpeedDialAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
+public final class SpeedDialAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder>
+ implements ItemTouchHelperAdapter {
@Retention(RetentionPolicy.SOURCE)
@IntDef({RowType.STARRED_HEADER, RowType.SUGGESTION_HEADER, RowType.STARRED, RowType.SUGGESTION})
@@ -74,6 +75,9 @@ public final class SpeedDialAdapter extends RecyclerView.Adapter<RecyclerView.Vi
private final Map<Integer, Integer> positionToRowTypeMap = new ArrayMap<>();
private List<SpeedDialUiItem> speedDialUiItems;
+ // Needed for FavoriteViewHolder
+ private ItemTouchHelper itemTouchHelper;
+
public SpeedDialAdapter(
Context context,
FavoriteContactsListener favoritesListener,
@@ -97,7 +101,9 @@ public final class SpeedDialAdapter extends RecyclerView.Adapter<RecyclerView.Vi
switch (viewType) {
case RowType.STARRED:
return new FavoritesViewHolder(
- inflater.inflate(R.layout.favorite_item_layout, parent, false), favoritesListener);
+ inflater.inflate(R.layout.favorite_item_layout, parent, false),
+ itemTouchHelper,
+ favoritesListener);
case RowType.SUGGESTION:
return new SuggestionViewHolder(
inflater.inflate(R.layout.suggestion_row_layout, parent, false), suggestedListener);
@@ -162,30 +168,46 @@ public final class SpeedDialAdapter extends RecyclerView.Adapter<RecyclerView.Vi
}
}
- /* package-private */ LayoutManager getLayoutManager(Context context) {
- GridLayoutManager layoutManager = new GridLayoutManager(context, 3 /* spanCount */);
- layoutManager.setSpanSizeLookup(
- new SpanSizeLookup() {
- @Override
- public int getSpanSize(int position) {
- return SpeedDialAdapter.this.getSpanSize(position);
- }
- });
- return layoutManager;
+ public SpanSizeLookup getSpanSizeLookup() {
+ return new SpanSizeLookup() {
+ @Override
+ public int getSpanSize(int position) {
+ switch (getItemViewType(position)) {
+ case RowType.SUGGESTION:
+ case RowType.STARRED_HEADER:
+ case RowType.SUGGESTION_HEADER:
+ return 3; // span the whole screen
+ case RowType.STARRED:
+ return 1; // span 1/3 of the screen
+ default:
+ throw Assert.createIllegalStateFailException(
+ "Invalid row type: " + positionToRowTypeMap.get(position));
+ }
+ }
+ };
}
- @VisibleForTesting
- int getSpanSize(int position) {
- switch (getItemViewType(position)) {
- case RowType.SUGGESTION:
- case RowType.STARRED_HEADER:
- case RowType.SUGGESTION_HEADER:
- return 3; // span the whole screen
- case RowType.STARRED:
- return 1; // span 1/3 of the screen
- default:
- throw Assert.createIllegalStateFailException(
- "Invalid row type: " + positionToRowTypeMap.get(position));
+ @Override
+ public void onItemMove(int fromPosition, int toPosition) {
+ if (fromPosition < toPosition) {
+ for (int i = fromPosition; i < toPosition && i < speedDialUiItems.size() - 1; i++) {
+ Collections.swap(speedDialUiItems, i, i + 1);
+ }
+ } else {
+ for (int i = fromPosition - 1; i > toPosition; i--) {
+ Collections.swap(speedDialUiItems, i, i - 1);
+ }
}
+ // TODO(calderwoodra): store pinned positions
+ notifyItemMoved(fromPosition, toPosition);
+ }
+
+ @Override
+ public boolean canDropOver(ViewHolder target) {
+ return target instanceof FavoritesViewHolder;
+ }
+
+ public void setItemTouchHelper(ItemTouchHelper itemTouchHelper) {
+ this.itemTouchHelper = itemTouchHelper;
}
}
diff --git a/java/com/android/dialer/speeddial/SpeedDialFragment.java b/java/com/android/dialer/speeddial/SpeedDialFragment.java
index d323b1bb4..b58d4abf4 100644
--- a/java/com/android/dialer/speeddial/SpeedDialFragment.java
+++ b/java/com/android/dialer/speeddial/SpeedDialFragment.java
@@ -21,6 +21,7 @@ import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v4.app.Fragment;
import android.support.v7.widget.RecyclerView;
+import android.support.v7.widget.helper.ItemTouchHelper;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
@@ -36,6 +37,8 @@ import com.android.dialer.speeddial.FavoritesViewHolder.FavoriteContactsListener
import com.android.dialer.speeddial.HeaderViewHolder.SpeedDialHeaderListener;
import com.android.dialer.speeddial.SuggestionViewHolder.SuggestedContactsListener;
import com.android.dialer.speeddial.database.SpeedDialEntry.Channel;
+import com.android.dialer.speeddial.draghelper.SpeedDialItemTouchHelperCallback;
+import com.android.dialer.speeddial.draghelper.SpeedDialLayoutManager;
import com.android.dialer.speeddial.loader.SpeedDialUiItem;
import com.android.dialer.speeddial.loader.UiItemLoaderComponent;
import com.google.common.collect.ImmutableList;
@@ -60,8 +63,10 @@ public class SpeedDialFragment extends Fragment {
private View rootLayout;
private ContextMenu contextMenu;
private FrameLayout contextMenuBackground;
- private SpeedDialAdapter adapter;
private ContextMenuItemListener contextMenuItemListener;
+
+ private SpeedDialAdapter adapter;
+ private SpeedDialLayoutManager layoutManager;
private SupportUiListener<ImmutableList<SpeedDialUiItem>> speedDialLoaderListener;
public static SpeedDialFragment newInstance() {
@@ -74,13 +79,23 @@ public class SpeedDialFragment extends Fragment {
LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
LogUtil.enterBlock("SpeedDialFragment.onCreateView");
rootLayout = inflater.inflate(R.layout.fragment_speed_dial, container, false);
- RecyclerView recyclerView = rootLayout.findViewById(R.id.speed_dial_recycler_view);
+ // Setup our RecyclerView
+ RecyclerView recyclerView = rootLayout.findViewById(R.id.speed_dial_recycler_view);
adapter =
new SpeedDialAdapter(getContext(), favoritesListener, suggestedListener, headerListener);
- recyclerView.setLayoutManager(adapter.getLayoutManager(getContext()));
+ layoutManager = new SpeedDialLayoutManager(getContext(), 3 /* spanCount */);
+ layoutManager.setSpanSizeLookup(adapter.getSpanSizeLookup());
+ recyclerView.setLayoutManager(layoutManager);
recyclerView.setAdapter(adapter);
+ // Setup drag and drop touch helper
+ ItemTouchHelper.Callback callback = new SpeedDialItemTouchHelperCallback(adapter);
+ ItemTouchHelper touchHelper = new ItemTouchHelper(callback);
+ touchHelper.attachToRecyclerView(recyclerView);
+ adapter.setItemTouchHelper(touchHelper);
+
+ // Setup favorite contact context menu
contextMenu = rootLayout.findViewById(R.id.favorite_contact_context_menu);
contextMenuBackground = rootLayout.findViewById(R.id.context_menu_background);
contextMenuBackground.setOnClickListener(
@@ -141,10 +156,26 @@ public class SpeedDialFragment extends Fragment {
}
@Override
- public void onLongClick(View view, SpeedDialUiItem speedDialUiItem) {
- contextMenuBackground.setVisibility(View.VISIBLE);
+ public void showContextMenu(View view, SpeedDialUiItem speedDialUiItem) {
+ layoutManager.setScrollEnabled(false);
contextMenu.showMenu(rootLayout, view, speedDialUiItem, contextMenuItemListener);
}
+
+ @Override
+ public void onTouchFinished(boolean closeContextMenu) {
+ layoutManager.setScrollEnabled(true);
+
+ if (closeContextMenu) {
+ contextMenu.hideMenu();
+ } else if (contextMenu.isVisible()) {
+ // If we're showing the context menu, show this background surface so that we can intercept
+ // touch events to close the menu
+ // Note: We call this in onTouchFinished because if we show the background before the user
+ // is done, they might try to drag the view and but won't be able to because this view would
+ // intercept all of the touch events.
+ contextMenuBackground.setVisibility(View.VISIBLE);
+ }
+ }
}
private final class SpeedDialSuggestedListener implements SuggestedContactsListener {
diff --git a/java/com/android/dialer/speeddial/draghelper/SpeedDialFavoritesViewHolderOnTouchListener.java b/java/com/android/dialer/speeddial/draghelper/SpeedDialFavoritesViewHolderOnTouchListener.java
new file mode 100644
index 000000000..00fecd788
--- /dev/null
+++ b/java/com/android/dialer/speeddial/draghelper/SpeedDialFavoritesViewHolderOnTouchListener.java
@@ -0,0 +1,107 @@
+/*
+ * Copyright (C) 2018 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.speeddial.draghelper;
+
+import android.support.v7.widget.RecyclerView.ViewHolder;
+import android.support.v7.widget.helper.ItemTouchHelper;
+import android.view.HapticFeedbackConstants;
+import android.view.MotionEvent;
+import android.view.View;
+import android.view.View.OnTouchListener;
+import android.view.ViewConfiguration;
+import com.android.dialer.common.Assert;
+
+/** OnTouchListener for the {@link com.android.dialer.speeddial.FavoritesViewHolder}. */
+public class SpeedDialFavoritesViewHolderOnTouchListener implements OnTouchListener {
+
+ private final ViewConfiguration configuration;
+ private final ItemTouchHelper itemTouchHelper;
+ private final ViewHolder viewHolder;
+ private final OnTouchFinishCallback onTouchFinishCallback;
+
+ private boolean hasPerformedLongClick;
+ private float startX;
+ private float startY;
+
+ public SpeedDialFavoritesViewHolderOnTouchListener(
+ ViewConfiguration configuration,
+ ItemTouchHelper itemTouchHelper,
+ ViewHolder viewHolder,
+ OnTouchFinishCallback onTouchFinishCallback) {
+ this.configuration = configuration;
+ this.itemTouchHelper = itemTouchHelper;
+ this.viewHolder = viewHolder;
+ this.onTouchFinishCallback = onTouchFinishCallback;
+ }
+
+ @Override
+ public boolean onTouch(View v, MotionEvent event) {
+ switch (event.getAction()) {
+ case MotionEvent.ACTION_DOWN:
+ startX = event.getX();
+ startY = event.getY();
+ return true;
+ case MotionEvent.ACTION_MOVE:
+ // If the user has long clicked the view
+ if (event.getEventTime() - event.getDownTime() > ViewConfiguration.getLongPressTimeout()) {
+ // Perform long click if we haven't already
+ if (!hasPerformedLongClick) {
+ v.performLongClick();
+ v.performHapticFeedback(HapticFeedbackConstants.LONG_PRESS);
+ hasPerformedLongClick = true;
+ } else if (moveEventExceedsTouchSlop(event)) {
+ itemTouchHelper.startDrag(viewHolder);
+ onTouchFinishCallback.onTouchFinished(true);
+ }
+ }
+ return true;
+ case MotionEvent.ACTION_UP:
+ if (event.getEventTime() - event.getDownTime() < ViewConfiguration.getLongPressTimeout()) {
+ v.performClick();
+ }
+ // fallthrough
+ case MotionEvent.ACTION_CANCEL:
+ hasPerformedLongClick = false;
+ onTouchFinishCallback.onTouchFinished(false);
+ return true;
+ default:
+ return false;
+ }
+ }
+
+ private boolean moveEventExceedsTouchSlop(MotionEvent event) {
+ Assert.checkArgument(event.getAction() == MotionEvent.ACTION_MOVE);
+ if (event.getHistorySize() <= 0) {
+ return false;
+ }
+
+ return Math.abs(startX - event.getX()) > configuration.getScaledTouchSlop()
+ || Math.abs(startY - event.getY()) > configuration.getScaledTouchSlop();
+ }
+
+ /** Callback to listen for on touch events ending. */
+ public interface OnTouchFinishCallback {
+
+ /**
+ * Called when the user stops touching the view.
+ *
+ * @see MotionEvent#ACTION_UP
+ * @see MotionEvent#ACTION_CANCEL
+ */
+ void onTouchFinished(boolean closeContextMenu);
+ }
+}
diff --git a/java/com/android/dialer/speeddial/draghelper/SpeedDialItemTouchHelperCallback.java b/java/com/android/dialer/speeddial/draghelper/SpeedDialItemTouchHelperCallback.java
new file mode 100644
index 000000000..d1d9f478b
--- /dev/null
+++ b/java/com/android/dialer/speeddial/draghelper/SpeedDialItemTouchHelperCallback.java
@@ -0,0 +1,83 @@
+/*
+ * Copyright (C) 2018 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.speeddial.draghelper;
+
+import android.support.annotation.NonNull;
+import android.support.v7.widget.RecyclerView;
+import android.support.v7.widget.RecyclerView.ViewHolder;
+import android.support.v7.widget.helper.ItemTouchHelper;
+
+/** {@link ItemTouchHelper} for Speed Dial favorite contacts. */
+public class SpeedDialItemTouchHelperCallback extends ItemTouchHelper.Callback {
+
+ private final ItemTouchHelperAdapter adapter;
+
+ public SpeedDialItemTouchHelperCallback(ItemTouchHelperAdapter adapter) {
+ this.adapter = adapter;
+ }
+
+ @Override
+ public boolean isLongPressDragEnabled() {
+ // We'll manually call ItemTouchHelper#startDrag
+ return false;
+ }
+
+ @Override
+ public boolean isItemViewSwipeEnabled() {
+ // We don't want to enable swiping
+ return false;
+ }
+
+ @Override
+ public boolean canDropOver(
+ @NonNull RecyclerView recyclerView, @NonNull ViewHolder current, @NonNull ViewHolder target) {
+ return adapter.canDropOver(target);
+ }
+
+ @Override
+ public int getMovementFlags(@NonNull RecyclerView recyclerView, @NonNull ViewHolder viewHolder) {
+ if (!adapter.canDropOver(viewHolder)) {
+ return makeMovementFlags(0, 0);
+ }
+
+ int dragFlags =
+ ItemTouchHelper.UP | ItemTouchHelper.DOWN | ItemTouchHelper.START | ItemTouchHelper.END;
+ return makeMovementFlags(dragFlags, /* swipeFlags */ 0);
+ }
+
+ @Override
+ public boolean onMove(
+ @NonNull RecyclerView recyclerView,
+ @NonNull ViewHolder viewHolder,
+ @NonNull ViewHolder target) {
+ adapter.onItemMove(viewHolder.getAdapterPosition(), target.getAdapterPosition());
+ return true;
+ }
+
+ @Override
+ public void onSwiped(@NonNull ViewHolder viewHolder, int direction) {
+ // No-op since we don't support swiping
+ }
+
+ /** RecyclerView adapters interested in drag and drop should implement this interface. */
+ public interface ItemTouchHelperAdapter {
+
+ void onItemMove(int fromPosition, int toPosition);
+
+ boolean canDropOver(ViewHolder target);
+ }
+}
diff --git a/java/com/android/dialer/speeddial/draghelper/SpeedDialLayoutManager.java b/java/com/android/dialer/speeddial/draghelper/SpeedDialLayoutManager.java
new file mode 100644
index 000000000..fcc925186
--- /dev/null
+++ b/java/com/android/dialer/speeddial/draghelper/SpeedDialLayoutManager.java
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2017 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.speeddial.draghelper;
+
+import android.content.Context;
+import android.support.v7.widget.GridLayoutManager;
+
+/** {@link GridLayoutManager} that allows disabling scrolling. */
+public class SpeedDialLayoutManager extends GridLayoutManager {
+
+ private boolean isScrollEnabled = true;
+
+ public SpeedDialLayoutManager(Context context, int spanCount) {
+ super(context, spanCount);
+ }
+
+ public void setScrollEnabled(boolean flag) {
+ this.isScrollEnabled = flag;
+ }
+
+ @Override
+ public boolean canScrollVertically() {
+ // Similarly you can customize "canScrollHorizontally()" for managing horizontal scroll
+ return isScrollEnabled && super.canScrollVertically();
+ }
+}