Loading packages/DocumentsUI/src/com/android/documentsui/Events.java +6 −1 Original line number Diff line number Diff line Loading @@ -138,7 +138,7 @@ public final class Events { int getItemPosition(); } public static final class MotionInputEvent implements InputEvent { public static final class MotionInputEvent implements InputEvent, AutoCloseable { private static final String TAG = "MotionInputEvent"; private static final Pools.SimplePool<MotionInputEvent> sPool = new Pools.SimplePool<>(1); Loading Loading @@ -199,6 +199,11 @@ public final class Events { assert(released); } @Override public void close() { recycle(); } @Override public boolean isMouseEvent() { return Events.isMouseEvent(mEvent); Loading packages/DocumentsUI/src/com/android/documentsui/RecentsCreateFragment.java +4 −8 Original line number Diff line number Diff line Loading @@ -52,13 +52,13 @@ import com.android.documentsui.model.DocumentStack; import com.android.documentsui.model.DurableUtils; import com.android.documentsui.model.RootInfo; import libcore.io.IoUtils; import java.io.IOException; import java.util.ArrayList; import java.util.Collection; import java.util.List; import libcore.io.IoUtils; /** * Display directories where recent creates took place. */ Loading Loading @@ -141,17 +141,13 @@ public class RecentsCreateFragment extends Fragment { new RecyclerView.OnItemTouchListener() { @Override public boolean onInterceptTouchEvent(RecyclerView rv, MotionEvent e) { final MotionInputEvent event = MotionInputEvent.obtain(e, mRecView); try { try (MotionInputEvent event = MotionInputEvent.obtain(e, mRecView)) { if (event.isOverItem() && event.isActionUp()) { final DocumentStack stack = mAdapter.getItem(event.getItemPosition()); ((BaseActivity) getActivity()).onStackPicked(stack); return true; } return false; } finally { event.recycle(); } } Loading Loading @@ -247,7 +243,7 @@ public class RecentsCreateFragment extends Fragment { final LayoutInflater inflater = LayoutInflater.from(context); return new StackHolder( (View) inflater.inflate(R.layout.item_doc_list, parent, false)); inflater.inflate(R.layout.item_doc_list, parent, false)); } @Override Loading packages/DocumentsUI/src/com/android/documentsui/dirlist/BandController.java +2 −8 Original line number Diff line number Diff line Loading @@ -85,21 +85,15 @@ public class BandController extends RecyclerView.OnScrollListener { new RecyclerView.OnItemTouchListener() { @Override public boolean onInterceptTouchEvent(RecyclerView rv, MotionEvent e) { final MotionInputEvent event = MotionInputEvent.obtain(e, view); try { try (MotionInputEvent event = MotionInputEvent.obtain(e, view)) { return handleEvent(event); } finally { event.recycle(); } } @Override public void onTouchEvent(RecyclerView rv, MotionEvent e) { if (Events.isMouseEvent(e)) { final MotionInputEvent event = MotionInputEvent.obtain(e, view); try { try (MotionInputEvent event = MotionInputEvent.obtain(e, view)) { processInputEvent(event); } finally { event.recycle(); } } } Loading packages/DocumentsUI/src/com/android/documentsui/dirlist/DirectoryFragment.java +46 −125 Original line number Diff line number Diff line Loading @@ -58,13 +58,11 @@ import android.util.SparseArray; import android.view.ActionMode; import android.view.ContextMenu; import android.view.DragEvent; import android.view.GestureDetector; import android.view.HapticFeedbackConstants; import android.view.LayoutInflater; import android.view.Menu; import android.view.MenuInflater; import android.view.MenuItem; import android.view.MotionEvent; import android.view.View; import android.view.ViewGroup; import android.widget.ImageView; Loading @@ -74,11 +72,9 @@ import android.widget.Toolbar; import com.android.documentsui.BaseActivity; import com.android.documentsui.DirectoryLoader; import com.android.documentsui.DirectoryResult; import com.android.documentsui.UrisSupplier; import com.android.documentsui.DocumentClipper; import com.android.documentsui.DocumentsActivity; import com.android.documentsui.DocumentsApplication; import com.android.documentsui.Events; import com.android.documentsui.Events.MotionInputEvent; import com.android.documentsui.ItemDragListener; import com.android.documentsui.MenuManager; Loading @@ -94,6 +90,7 @@ import com.android.documentsui.Shared; import com.android.documentsui.Snackbars; import com.android.documentsui.State; import com.android.documentsui.State.ViewMode; import com.android.documentsui.UrisSupplier; import com.android.documentsui.dirlist.MultiSelectManager.Selection; import com.android.documentsui.model.DocumentInfo; import com.android.documentsui.model.RootInfo; Loading Loading @@ -295,22 +292,27 @@ public class DirectoryFragment extends Fragment } mRecView.setLayoutManager(mLayout); mGestureDetector = new ListeningGestureDetector(this.getContext(), mDragHelper, new GestureListener()); mRecView.addOnItemTouchListener(mGestureDetector); mEmptyView.setOnTouchListener(mGestureDetector); // TODO: instead of inserting the view into the constructor, extract listener-creation code // and set the listener on the view after the fact. Then the view doesn't need to be passed // into the selection manager. mSelectionManager = new MultiSelectManager( mRecView, mAdapter, state.allowMultiple ? MultiSelectManager.MODE_MULTIPLE : MultiSelectManager.MODE_SINGLE, null); : MultiSelectManager.MODE_SINGLE); GestureListener gestureListener = new GestureListener( mSelectionManager, mRecView, this::getTarget, this::onDoubleTap, this::onRightClick); mGestureDetector = new ListeningGestureDetector(this.getContext(), mDragHelper, gestureListener); mRecView.addOnItemTouchListener(mGestureDetector); mEmptyView.setOnTouchListener(mGestureDetector); if (state.allowMultiple) { mBandController = new BandController(mRecView, mAdapter, mSelectionManager); Loading Loading @@ -426,12 +428,9 @@ public class DirectoryFragment extends Fragment return false; } protected boolean onRightClick(MotionEvent e) { // First get target to see if it's a blank window or a file/doc final MotionInputEvent event = MotionInputEvent.obtain(e, mRecView); try { if (event.getItemPosition() != RecyclerView.NO_POSITION) { final DocumentHolder holder = getTarget(event); protected boolean onRightClick(MotionInputEvent e) { if (e.getItemPosition() != RecyclerView.NO_POSITION) { final DocumentHolder holder = getTarget(e); String modelId = getModelId(holder.itemView); if (!mSelectionManager.getSelection().contains(modelId)) { mSelectionManager.clearSelection(); Loading Loading @@ -462,9 +461,6 @@ public class DirectoryFragment extends Fragment mRecView.showContextMenu(e.getX(), e.getY()); unregisterForContextMenu(mRecView); } } finally { event.recycle(); } return true; } Loading Loading @@ -1554,81 +1550,6 @@ public class DirectoryFragment extends Fragment return mTuner.canSelectType(docMimeType, docFlags); } /** * The gesture listener for items in the list/grid view. Interprets gestures and sends the * events to the target DocumentHolder, whence they are routed to the appropriate listener. */ class GestureListener extends GestureDetector.SimpleOnGestureListener { // From the RecyclerView, we get two events sent to // ListeningGestureDetector#onInterceptTouchEvent on a mouse click; we first get an // ACTION_DOWN Event for clicking on the mouse, and then an ACTION_UP event from releasing // the mouse click. ACTION_UP event doesn't have information regarding the button (primary // vs. secondary), so we have to save that somewhere first from ACTION_DOWN, and then reuse // it later. The ACTION_DOWN event doesn't get forwarded to GestureListener, so we have open // up a public set method to set it. private int mLastButtonState = -1; public void setLastButtonState(int state) { mLastButtonState = state; } @Override public boolean onSingleTapUp(MotionEvent e) { // Single tap logic: // We first see if it's a mouse event, and if it was right click by checking on // @{code ListeningGestureDetector#mLastButtonState} // If the selection manager is active, it gets first whack at handling tap // events. Otherwise, tap events are routed to the target DocumentHolder. if (Events.isMouseEvent(e) && mLastButtonState == MotionEvent.BUTTON_SECONDARY) { mLastButtonState = -1; return onRightClick(e); } final MotionInputEvent event = MotionInputEvent.obtain(e, mRecView); try { boolean handled = mSelectionManager.onSingleTapUp(event); if (handled) { return handled; } // Give the DocumentHolder a crack at the event. DocumentHolder holder = DirectoryFragment.this.getTarget(event); if (holder != null) { handled = holder.onSingleTapUp(e); } return handled; } finally { event.recycle(); } } @Override public void onLongPress(MotionEvent e) { // Long-press events get routed directly to the selection manager. They can be // changed to route through the DocumentHolder if necessary. final MotionInputEvent event = MotionInputEvent.obtain(e, mRecView); try { mSelectionManager.onLongPress(event); } finally { event.recycle(); } } @Override public boolean onDoubleTap(MotionEvent e) { // Double-tap events are handled directly by the DirectoryFragment. They can be changed // to route through the DocumentHolder if necessary. final MotionInputEvent event = MotionInputEvent.obtain(e, mRecView); return DirectoryFragment.this.onDoubleTap(event); } public boolean onRightClick(MotionEvent e) { return DirectoryFragment.this.onRightClick(e); } } public static void showDirectory( FragmentManager fm, RootInfo root, DocumentInfo doc, int anim) { create(fm, TYPE_NORMAL, root, doc, null, anim); Loading packages/DocumentsUI/src/com/android/documentsui/dirlist/GestureListener.java 0 → 100644 +118 −0 Original line number Diff line number Diff line /* * Copyright (C) 2016 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.documentsui.dirlist; import android.support.v7.widget.RecyclerView; import android.view.GestureDetector; import android.view.MotionEvent; import com.android.documentsui.Events; import com.android.documentsui.Events.MotionInputEvent; import java.util.function.Function; import java.util.function.Predicate; /** * The gesture listener for items in the directly list, interprets gestures, and sends the * events to the target DocumentHolder, whence they are routed to the appropriate listener. */ final class GestureListener extends GestureDetector.SimpleOnGestureListener { // From the RecyclerView, we get two events sent to // ListeningGestureDetector#onInterceptTouchEvent on a mouse click; we first get an // ACTION_DOWN Event for clicking on the mouse, and then an ACTION_UP event from releasing // the mouse click. ACTION_UP event doesn't have information regarding the button (primary // vs. secondary), so we have to save that somewhere first from ACTION_DOWN, and then reuse // it later. The ACTION_DOWN event doesn't get forwarded to GestureListener, so we have open // up a public set method to set it. private int mLastButtonState = -1; private MultiSelectManager mSelectionMgr; private RecyclerView mRecView; private Function<MotionInputEvent, DocumentHolder> mDocFinder; private Predicate<MotionInputEvent> mDoubleTapHandler; private Predicate<MotionInputEvent> mRightClickHandler; public GestureListener( MultiSelectManager selectionMgr, RecyclerView recView, Function<MotionInputEvent, DocumentHolder> docFinder, Predicate<MotionInputEvent> doubleTapHandler, Predicate<MotionInputEvent> rightClickHandler) { mSelectionMgr = selectionMgr; mRecView = recView; mDocFinder = docFinder; mDoubleTapHandler = doubleTapHandler; mRightClickHandler = rightClickHandler; } public void setLastButtonState(int state) { mLastButtonState = state; } @Override public boolean onSingleTapUp(MotionEvent e) { // Single tap logic: // We first see if it's a mouse event, and if it was right click by checking on // @{code ListeningGestureDetector#mLastButtonState} // If the selection manager is active, it gets first whack at handling tap // events. Otherwise, tap events are routed to the target DocumentHolder. if (Events.isMouseEvent(e) && mLastButtonState == MotionEvent.BUTTON_SECONDARY) { mLastButtonState = -1; return onRightClick(e); } try (MotionInputEvent event = MotionInputEvent.obtain(e, mRecView)) { boolean handled = mSelectionMgr.onSingleTapUp(event); if (handled) { return handled; } // Give the DocumentHolder a crack at the event. DocumentHolder holder = mDocFinder.apply(event); if (holder != null) { handled = holder.onSingleTapUp(e); } return handled; } } @Override public void onLongPress(MotionEvent e) { // Long-press events get routed directly to the selection manager. They can be // changed to route through the DocumentHolder if necessary. try (MotionInputEvent event = MotionInputEvent.obtain(e, mRecView)) { mSelectionMgr.onLongPress(event); } } @Override public boolean onDoubleTap(MotionEvent e) { // Double-tap events are handled directly by the DirectoryFragment. They can be changed // to route through the DocumentHolder if necessary. try (MotionInputEvent event = MotionInputEvent.obtain(e, mRecView)) { return mDoubleTapHandler.test(event); } } public boolean onRightClick(MotionEvent e) { try (MotionInputEvent event = MotionInputEvent.obtain(e, mRecView)) { return mRightClickHandler.test(event); } } } No newline at end of file Loading
packages/DocumentsUI/src/com/android/documentsui/Events.java +6 −1 Original line number Diff line number Diff line Loading @@ -138,7 +138,7 @@ public final class Events { int getItemPosition(); } public static final class MotionInputEvent implements InputEvent { public static final class MotionInputEvent implements InputEvent, AutoCloseable { private static final String TAG = "MotionInputEvent"; private static final Pools.SimplePool<MotionInputEvent> sPool = new Pools.SimplePool<>(1); Loading Loading @@ -199,6 +199,11 @@ public final class Events { assert(released); } @Override public void close() { recycle(); } @Override public boolean isMouseEvent() { return Events.isMouseEvent(mEvent); Loading
packages/DocumentsUI/src/com/android/documentsui/RecentsCreateFragment.java +4 −8 Original line number Diff line number Diff line Loading @@ -52,13 +52,13 @@ import com.android.documentsui.model.DocumentStack; import com.android.documentsui.model.DurableUtils; import com.android.documentsui.model.RootInfo; import libcore.io.IoUtils; import java.io.IOException; import java.util.ArrayList; import java.util.Collection; import java.util.List; import libcore.io.IoUtils; /** * Display directories where recent creates took place. */ Loading Loading @@ -141,17 +141,13 @@ public class RecentsCreateFragment extends Fragment { new RecyclerView.OnItemTouchListener() { @Override public boolean onInterceptTouchEvent(RecyclerView rv, MotionEvent e) { final MotionInputEvent event = MotionInputEvent.obtain(e, mRecView); try { try (MotionInputEvent event = MotionInputEvent.obtain(e, mRecView)) { if (event.isOverItem() && event.isActionUp()) { final DocumentStack stack = mAdapter.getItem(event.getItemPosition()); ((BaseActivity) getActivity()).onStackPicked(stack); return true; } return false; } finally { event.recycle(); } } Loading Loading @@ -247,7 +243,7 @@ public class RecentsCreateFragment extends Fragment { final LayoutInflater inflater = LayoutInflater.from(context); return new StackHolder( (View) inflater.inflate(R.layout.item_doc_list, parent, false)); inflater.inflate(R.layout.item_doc_list, parent, false)); } @Override Loading
packages/DocumentsUI/src/com/android/documentsui/dirlist/BandController.java +2 −8 Original line number Diff line number Diff line Loading @@ -85,21 +85,15 @@ public class BandController extends RecyclerView.OnScrollListener { new RecyclerView.OnItemTouchListener() { @Override public boolean onInterceptTouchEvent(RecyclerView rv, MotionEvent e) { final MotionInputEvent event = MotionInputEvent.obtain(e, view); try { try (MotionInputEvent event = MotionInputEvent.obtain(e, view)) { return handleEvent(event); } finally { event.recycle(); } } @Override public void onTouchEvent(RecyclerView rv, MotionEvent e) { if (Events.isMouseEvent(e)) { final MotionInputEvent event = MotionInputEvent.obtain(e, view); try { try (MotionInputEvent event = MotionInputEvent.obtain(e, view)) { processInputEvent(event); } finally { event.recycle(); } } } Loading
packages/DocumentsUI/src/com/android/documentsui/dirlist/DirectoryFragment.java +46 −125 Original line number Diff line number Diff line Loading @@ -58,13 +58,11 @@ import android.util.SparseArray; import android.view.ActionMode; import android.view.ContextMenu; import android.view.DragEvent; import android.view.GestureDetector; import android.view.HapticFeedbackConstants; import android.view.LayoutInflater; import android.view.Menu; import android.view.MenuInflater; import android.view.MenuItem; import android.view.MotionEvent; import android.view.View; import android.view.ViewGroup; import android.widget.ImageView; Loading @@ -74,11 +72,9 @@ import android.widget.Toolbar; import com.android.documentsui.BaseActivity; import com.android.documentsui.DirectoryLoader; import com.android.documentsui.DirectoryResult; import com.android.documentsui.UrisSupplier; import com.android.documentsui.DocumentClipper; import com.android.documentsui.DocumentsActivity; import com.android.documentsui.DocumentsApplication; import com.android.documentsui.Events; import com.android.documentsui.Events.MotionInputEvent; import com.android.documentsui.ItemDragListener; import com.android.documentsui.MenuManager; Loading @@ -94,6 +90,7 @@ import com.android.documentsui.Shared; import com.android.documentsui.Snackbars; import com.android.documentsui.State; import com.android.documentsui.State.ViewMode; import com.android.documentsui.UrisSupplier; import com.android.documentsui.dirlist.MultiSelectManager.Selection; import com.android.documentsui.model.DocumentInfo; import com.android.documentsui.model.RootInfo; Loading Loading @@ -295,22 +292,27 @@ public class DirectoryFragment extends Fragment } mRecView.setLayoutManager(mLayout); mGestureDetector = new ListeningGestureDetector(this.getContext(), mDragHelper, new GestureListener()); mRecView.addOnItemTouchListener(mGestureDetector); mEmptyView.setOnTouchListener(mGestureDetector); // TODO: instead of inserting the view into the constructor, extract listener-creation code // and set the listener on the view after the fact. Then the view doesn't need to be passed // into the selection manager. mSelectionManager = new MultiSelectManager( mRecView, mAdapter, state.allowMultiple ? MultiSelectManager.MODE_MULTIPLE : MultiSelectManager.MODE_SINGLE, null); : MultiSelectManager.MODE_SINGLE); GestureListener gestureListener = new GestureListener( mSelectionManager, mRecView, this::getTarget, this::onDoubleTap, this::onRightClick); mGestureDetector = new ListeningGestureDetector(this.getContext(), mDragHelper, gestureListener); mRecView.addOnItemTouchListener(mGestureDetector); mEmptyView.setOnTouchListener(mGestureDetector); if (state.allowMultiple) { mBandController = new BandController(mRecView, mAdapter, mSelectionManager); Loading Loading @@ -426,12 +428,9 @@ public class DirectoryFragment extends Fragment return false; } protected boolean onRightClick(MotionEvent e) { // First get target to see if it's a blank window or a file/doc final MotionInputEvent event = MotionInputEvent.obtain(e, mRecView); try { if (event.getItemPosition() != RecyclerView.NO_POSITION) { final DocumentHolder holder = getTarget(event); protected boolean onRightClick(MotionInputEvent e) { if (e.getItemPosition() != RecyclerView.NO_POSITION) { final DocumentHolder holder = getTarget(e); String modelId = getModelId(holder.itemView); if (!mSelectionManager.getSelection().contains(modelId)) { mSelectionManager.clearSelection(); Loading Loading @@ -462,9 +461,6 @@ public class DirectoryFragment extends Fragment mRecView.showContextMenu(e.getX(), e.getY()); unregisterForContextMenu(mRecView); } } finally { event.recycle(); } return true; } Loading Loading @@ -1554,81 +1550,6 @@ public class DirectoryFragment extends Fragment return mTuner.canSelectType(docMimeType, docFlags); } /** * The gesture listener for items in the list/grid view. Interprets gestures and sends the * events to the target DocumentHolder, whence they are routed to the appropriate listener. */ class GestureListener extends GestureDetector.SimpleOnGestureListener { // From the RecyclerView, we get two events sent to // ListeningGestureDetector#onInterceptTouchEvent on a mouse click; we first get an // ACTION_DOWN Event for clicking on the mouse, and then an ACTION_UP event from releasing // the mouse click. ACTION_UP event doesn't have information regarding the button (primary // vs. secondary), so we have to save that somewhere first from ACTION_DOWN, and then reuse // it later. The ACTION_DOWN event doesn't get forwarded to GestureListener, so we have open // up a public set method to set it. private int mLastButtonState = -1; public void setLastButtonState(int state) { mLastButtonState = state; } @Override public boolean onSingleTapUp(MotionEvent e) { // Single tap logic: // We first see if it's a mouse event, and if it was right click by checking on // @{code ListeningGestureDetector#mLastButtonState} // If the selection manager is active, it gets first whack at handling tap // events. Otherwise, tap events are routed to the target DocumentHolder. if (Events.isMouseEvent(e) && mLastButtonState == MotionEvent.BUTTON_SECONDARY) { mLastButtonState = -1; return onRightClick(e); } final MotionInputEvent event = MotionInputEvent.obtain(e, mRecView); try { boolean handled = mSelectionManager.onSingleTapUp(event); if (handled) { return handled; } // Give the DocumentHolder a crack at the event. DocumentHolder holder = DirectoryFragment.this.getTarget(event); if (holder != null) { handled = holder.onSingleTapUp(e); } return handled; } finally { event.recycle(); } } @Override public void onLongPress(MotionEvent e) { // Long-press events get routed directly to the selection manager. They can be // changed to route through the DocumentHolder if necessary. final MotionInputEvent event = MotionInputEvent.obtain(e, mRecView); try { mSelectionManager.onLongPress(event); } finally { event.recycle(); } } @Override public boolean onDoubleTap(MotionEvent e) { // Double-tap events are handled directly by the DirectoryFragment. They can be changed // to route through the DocumentHolder if necessary. final MotionInputEvent event = MotionInputEvent.obtain(e, mRecView); return DirectoryFragment.this.onDoubleTap(event); } public boolean onRightClick(MotionEvent e) { return DirectoryFragment.this.onRightClick(e); } } public static void showDirectory( FragmentManager fm, RootInfo root, DocumentInfo doc, int anim) { create(fm, TYPE_NORMAL, root, doc, null, anim); Loading
packages/DocumentsUI/src/com/android/documentsui/dirlist/GestureListener.java 0 → 100644 +118 −0 Original line number Diff line number Diff line /* * Copyright (C) 2016 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.documentsui.dirlist; import android.support.v7.widget.RecyclerView; import android.view.GestureDetector; import android.view.MotionEvent; import com.android.documentsui.Events; import com.android.documentsui.Events.MotionInputEvent; import java.util.function.Function; import java.util.function.Predicate; /** * The gesture listener for items in the directly list, interprets gestures, and sends the * events to the target DocumentHolder, whence they are routed to the appropriate listener. */ final class GestureListener extends GestureDetector.SimpleOnGestureListener { // From the RecyclerView, we get two events sent to // ListeningGestureDetector#onInterceptTouchEvent on a mouse click; we first get an // ACTION_DOWN Event for clicking on the mouse, and then an ACTION_UP event from releasing // the mouse click. ACTION_UP event doesn't have information regarding the button (primary // vs. secondary), so we have to save that somewhere first from ACTION_DOWN, and then reuse // it later. The ACTION_DOWN event doesn't get forwarded to GestureListener, so we have open // up a public set method to set it. private int mLastButtonState = -1; private MultiSelectManager mSelectionMgr; private RecyclerView mRecView; private Function<MotionInputEvent, DocumentHolder> mDocFinder; private Predicate<MotionInputEvent> mDoubleTapHandler; private Predicate<MotionInputEvent> mRightClickHandler; public GestureListener( MultiSelectManager selectionMgr, RecyclerView recView, Function<MotionInputEvent, DocumentHolder> docFinder, Predicate<MotionInputEvent> doubleTapHandler, Predicate<MotionInputEvent> rightClickHandler) { mSelectionMgr = selectionMgr; mRecView = recView; mDocFinder = docFinder; mDoubleTapHandler = doubleTapHandler; mRightClickHandler = rightClickHandler; } public void setLastButtonState(int state) { mLastButtonState = state; } @Override public boolean onSingleTapUp(MotionEvent e) { // Single tap logic: // We first see if it's a mouse event, and if it was right click by checking on // @{code ListeningGestureDetector#mLastButtonState} // If the selection manager is active, it gets first whack at handling tap // events. Otherwise, tap events are routed to the target DocumentHolder. if (Events.isMouseEvent(e) && mLastButtonState == MotionEvent.BUTTON_SECONDARY) { mLastButtonState = -1; return onRightClick(e); } try (MotionInputEvent event = MotionInputEvent.obtain(e, mRecView)) { boolean handled = mSelectionMgr.onSingleTapUp(event); if (handled) { return handled; } // Give the DocumentHolder a crack at the event. DocumentHolder holder = mDocFinder.apply(event); if (holder != null) { handled = holder.onSingleTapUp(e); } return handled; } } @Override public void onLongPress(MotionEvent e) { // Long-press events get routed directly to the selection manager. They can be // changed to route through the DocumentHolder if necessary. try (MotionInputEvent event = MotionInputEvent.obtain(e, mRecView)) { mSelectionMgr.onLongPress(event); } } @Override public boolean onDoubleTap(MotionEvent e) { // Double-tap events are handled directly by the DirectoryFragment. They can be changed // to route through the DocumentHolder if necessary. try (MotionInputEvent event = MotionInputEvent.obtain(e, mRecView)) { return mDoubleTapHandler.test(event); } } public boolean onRightClick(MotionEvent e) { try (MotionInputEvent event = MotionInputEvent.obtain(e, mRecView)) { return mRightClickHandler.test(event); } } } No newline at end of file