diff --git a/packages/DocumentsUI/src/com/android/documentsui/dirlist/DirectoryFragment.java b/packages/DocumentsUI/src/com/android/documentsui/dirlist/DirectoryFragment.java index 2fae24a16c56e..46ae67fc8d830 100644 --- a/packages/DocumentsUI/src/com/android/documentsui/dirlist/DirectoryFragment.java +++ b/packages/DocumentsUI/src/com/android/documentsui/dirlist/DirectoryFragment.java @@ -263,7 +263,7 @@ public class DirectoryFragment extends Fragment implements DocumentsAdapter.Envi mSelectionManager.addCallback(selectionListener); // Make sure this is done after the RecyclerView is set up. - mFocusManager = new FocusManager(mRecView, mSelectionManager); + mFocusManager = new FocusManager(mRecView); mModel = new Model(); mModel.addUpdateListener(mAdapter); @@ -1261,6 +1261,18 @@ public class DirectoryFragment extends Fragment implements DocumentsAdapter.Envi } if (mFocusManager.handleKey(doc, keyCode, event)) { + // Handle range selection adjustments. Extending the selection will adjust the + // bounds of the in-progress range selection. Each time an unshifted navigation + // event is received, the range selection is restarted. + if (shouldExtendSelection(event)) { + if (!mSelectionManager.isRangeSelectionActive()) { + // Start a range selection if one isn't active + mSelectionManager.startRangeSelection(doc.getAdapterPosition()); + } + mSelectionManager.snapRangeSelection(mFocusManager.getFocusPosition()); + } else { + mSelectionManager.endRangeSelection(); + } return true; } @@ -1275,6 +1287,11 @@ public class DirectoryFragment extends Fragment implements DocumentsAdapter.Envi return false; } + + private boolean shouldExtendSelection(KeyEvent event) { + return Events.isNavigationKeyCode(event.getKeyCode()) && + event.isShiftPressed(); + } } private final class ModelUpdateListener implements Model.UpdateListener { diff --git a/packages/DocumentsUI/src/com/android/documentsui/dirlist/FocusManager.java b/packages/DocumentsUI/src/com/android/documentsui/dirlist/FocusManager.java index 295505a30d924..cce3e22c23be8 100644 --- a/packages/DocumentsUI/src/com/android/documentsui/dirlist/FocusManager.java +++ b/packages/DocumentsUI/src/com/android/documentsui/dirlist/FocusManager.java @@ -33,15 +33,13 @@ class FocusManager implements View.OnFocusChangeListener { private RecyclerView mView; private RecyclerView.Adapter> mAdapter; private LinearLayoutManager mLayout; - private MultiSelectManager mSelectionManager; private int mLastFocusPosition = RecyclerView.NO_POSITION; - public FocusManager(RecyclerView view, MultiSelectManager selectionManager) { + public FocusManager(RecyclerView view) { mView = view; mAdapter = view.getAdapter(); mLayout = (LinearLayoutManager) view.getLayoutManager(); - mSelectionManager = selectionManager; } /** @@ -72,13 +70,6 @@ class FocusManager implements View.OnFocusChangeListener { if (endPos != RecyclerView.NO_POSITION) { focusItem(endPos); - boolean extendSelection = event.isShiftPressed(); - - // Handle any necessary adjustments to selection. - if (extendSelection) { - int startPos = doc.getAdapterPosition(); - mSelectionManager.selectRange(startPos, endPos); - } } // Swallow all navigation keystrokes. Otherwise they go to the app's global // key-handler, which will route them back to the DF and cause focus to be reset. @@ -108,6 +99,13 @@ class FocusManager implements View.OnFocusChangeListener { } } + /** + * @return The adapter position of the last focused item. + */ + public int getFocusPosition() { + return mLastFocusPosition; + } + /** * Finds the destination position where the focus should land for a given navigation event. * diff --git a/packages/DocumentsUI/src/com/android/documentsui/dirlist/MultiSelectManager.java b/packages/DocumentsUI/src/com/android/documentsui/dirlist/MultiSelectManager.java index d60825baa7cf0..c8b6f85282720 100644 --- a/packages/DocumentsUI/src/com/android/documentsui/dirlist/MultiSelectManager.java +++ b/packages/DocumentsUI/src/com/android/documentsui/dirlist/MultiSelectManager.java @@ -370,39 +370,41 @@ public final class MultiSelectManager { } /** - * Handle a range selection event. - *