Loading src/com/android/documentsui/dirlist/DragHoverListener.java→src/com/android/documentsui/DragHoverListener.java +35 −19 Original line number Diff line number Diff line Loading @@ -14,21 +14,22 @@ * limitations under the License. */ package com.android.documentsui.dirlist; package com.android.documentsui; import android.graphics.Point; import androidx.annotation.VisibleForTesting; import android.view.DragEvent; import android.view.View; import android.view.View.OnDragListener; import android.widget.AbsListView; import com.android.documentsui.ItemDragListener; import com.android.documentsui.ItemDragListener.DragHost; import com.android.documentsui.selection.ViewAutoScroller; import com.android.documentsui.selection.ViewAutoScroller.ScrollHost; import com.android.documentsui.selection.ViewAutoScroller.ScrollerCallbacks; import java.util.function.BooleanSupplier; import java.util.function.IntConsumer; import java.util.function.IntSupplier; import java.util.function.Predicate; Loading @@ -36,9 +37,9 @@ import javax.annotation.Nullable; /** * This class acts as a middle-man handler for potential auto-scrolling before passing the dragEvent * onto {@link DirectoryDragListener}. * onto {@link ItemDragListener}. */ class DragHoverListener implements OnDragListener { public class DragHoverListener implements OnDragListener { private final ItemDragListener<? extends DragHost> mDragHandler; private final IntSupplier mHeight; Loading @@ -47,12 +48,12 @@ class DragHoverListener implements OnDragListener { private final Runnable mDragScroller; /** * Predicate to tests whether it's the scroll view ({@link DirectoryFragment#mRecView}) itself. * Predicate to tests whether it's the scroll view itself. * * {@link DragHoverListener} is used for both {@link DirectoryFragment#mRecView} and its * children. When we decide whether it's in the scroll zone we need to obtain the coordinate * relative to {@link DirectoryFragment#mRecView} so we need to transform the coordinate if the * view that gets drag and drop events is a child of {@link DirectoryFragment#mRecView}. * {@link DragHoverListener} is used for both the scroll view and its children. * When we decide whether it's in the scroll zone we need to obtain the coordinate * relative to container view so we need to transform the coordinate if the view * that gets drag and drop events is a child of scroll view. */ private final Predicate<View> mIsScrollView; Loading Loading @@ -94,20 +95,37 @@ class DragHoverListener implements OnDragListener { mDragScroller = new ViewAutoScroller(scrollHost, scrollCallbacks); } static DragHoverListener create( public static DragHoverListener create( ItemDragListener<? extends DragHost> dragHandler, AbsListView scrollView) { return create(dragHandler, scrollView, scrollView::scrollListBy); } public static DragHoverListener create( ItemDragListener<? extends DragHost> dragHandler, View scrollView) { return create( dragHandler, scrollView, (int dy) -> { scrollView.scrollBy(0, dy); }); } static DragHoverListener create( ItemDragListener<? extends DragHost> dragHandler, View scrollView, IntConsumer scroller) { ScrollerCallbacks scrollCallbacks = new ScrollerCallbacks() { @Override public void scrollBy(int dy) { scrollView.scrollBy(0, dy); scroller.accept(dy); } @Override public void runAtNextFrame(Runnable r) { scrollView.postOnAnimation(r); } @Override Loading @@ -116,15 +134,13 @@ class DragHoverListener implements OnDragListener { } }; DragHoverListener listener = new DragHoverListener( return new DragHoverListener( dragHandler, scrollView::getHeight, (view) -> (scrollView == view), () -> scrollView.canScrollVertically(-1), () -> scrollView.canScrollVertically(1), scrollCallbacks); return listener; } @Override Loading Loading @@ -157,9 +173,9 @@ class DragHoverListener implements OnDragListener { } private Point transformToScrollViewCoordinate(View v, float x, float y) { // Check if v is the RecyclerView itself. If not we need to transform the coordinate to // relative to the RecyclerView because we need to test the scroll zone in the coordinate // relative to the RecyclerView; if yes we don't need to transform coordinates. // Check if v is the scroll view itself. If not we need to transform the coordinate to // relative to the scroll view because we need to test the scroll zone in the coordinate // relative to the scroll view; if yes we don't need to transform coordinates. final boolean isScrollView = mIsScrollView.test(v); final float offsetX = isScrollView ? 0 : v.getX(); final float offsetY = isScrollView ? 0 : v.getY(); Loading src/com/android/documentsui/ItemDragListener.java +12 −0 Original line number Diff line number Diff line Loading @@ -63,6 +63,10 @@ public class ItemDragListener<H extends DragHost> implements OnDragListener { @Override public boolean onDrag(final View v, DragEvent event) { if (!mDragHost.canHandleDragEvent(v)) { return false; } switch (event.getAction()) { case DragEvent.ACTION_DRAG_STARTED: return true; Loading Loading @@ -193,5 +197,13 @@ public class ItemDragListener<H extends DragHost> implements OnDragListener { * Notifies when the drag and drop has ended. */ void onDragEnded(); /** * Whether drag events can dispatch to the view. * @param v the view being to receive drag events */ default boolean canHandleDragEvent(View v) { return true; } } } src/com/android/documentsui/dirlist/DirectoryFragment.java +1 −0 Original line number Diff line number Diff line Loading @@ -64,6 +64,7 @@ import com.android.documentsui.ActionModeController; import com.android.documentsui.BaseActivity; import com.android.documentsui.BaseActivity.RetainedState; import com.android.documentsui.DocumentsApplication; import com.android.documentsui.DragHoverListener; import com.android.documentsui.FocusManager; import com.android.documentsui.Injector; import com.android.documentsui.Injector.ContentScoped; Loading src/com/android/documentsui/sidebar/DragHost.java +5 −0 Original line number Diff line number Diff line Loading @@ -55,6 +55,11 @@ class DragHost extends AbstractDragHost { mActivity.runOnUiThread(runnable); } @Override public boolean canHandleDragEvent(View v) { return v instanceof RootItemView; } @Override public void setDropTargetHighlight(View v, boolean highlight) { // SpacerView doesn't have DragListener so this view is guaranteed to be a RootItemView. Loading src/com/android/documentsui/sidebar/RootsFragment.java +4 −1 Original line number Diff line number Diff line Loading @@ -52,6 +52,7 @@ import android.widget.ListView; import com.android.documentsui.ActionHandler; import com.android.documentsui.BaseActivity; import com.android.documentsui.DocumentsApplication; import com.android.documentsui.DragHoverListener; import com.android.documentsui.Injector; import com.android.documentsui.Injector.Injected; import com.android.documentsui.ItemDragListener; Loading Loading @@ -197,7 +198,7 @@ public class RootsFragment extends Fragment { DocumentsApplication.getDragAndDropManager(activity), this::getItem, mActionHandler); mDragListener = new ItemDragListener<DragHost>(host) { final ItemDragListener<DragHost> listener = new ItemDragListener<DragHost>(host) { @Override public boolean handleDropEventChecked(View v, DragEvent event) { final Item item = getItem(v); Loading @@ -207,6 +208,8 @@ public class RootsFragment extends Fragment { return item.dropOn(event); } }; mDragListener = DragHoverListener.create(listener, mList); mList.setOnDragListener(mDragListener); } mCallbacks = new LoaderCallbacks<Collection<RootInfo>>() { Loading Loading
src/com/android/documentsui/dirlist/DragHoverListener.java→src/com/android/documentsui/DragHoverListener.java +35 −19 Original line number Diff line number Diff line Loading @@ -14,21 +14,22 @@ * limitations under the License. */ package com.android.documentsui.dirlist; package com.android.documentsui; import android.graphics.Point; import androidx.annotation.VisibleForTesting; import android.view.DragEvent; import android.view.View; import android.view.View.OnDragListener; import android.widget.AbsListView; import com.android.documentsui.ItemDragListener; import com.android.documentsui.ItemDragListener.DragHost; import com.android.documentsui.selection.ViewAutoScroller; import com.android.documentsui.selection.ViewAutoScroller.ScrollHost; import com.android.documentsui.selection.ViewAutoScroller.ScrollerCallbacks; import java.util.function.BooleanSupplier; import java.util.function.IntConsumer; import java.util.function.IntSupplier; import java.util.function.Predicate; Loading @@ -36,9 +37,9 @@ import javax.annotation.Nullable; /** * This class acts as a middle-man handler for potential auto-scrolling before passing the dragEvent * onto {@link DirectoryDragListener}. * onto {@link ItemDragListener}. */ class DragHoverListener implements OnDragListener { public class DragHoverListener implements OnDragListener { private final ItemDragListener<? extends DragHost> mDragHandler; private final IntSupplier mHeight; Loading @@ -47,12 +48,12 @@ class DragHoverListener implements OnDragListener { private final Runnable mDragScroller; /** * Predicate to tests whether it's the scroll view ({@link DirectoryFragment#mRecView}) itself. * Predicate to tests whether it's the scroll view itself. * * {@link DragHoverListener} is used for both {@link DirectoryFragment#mRecView} and its * children. When we decide whether it's in the scroll zone we need to obtain the coordinate * relative to {@link DirectoryFragment#mRecView} so we need to transform the coordinate if the * view that gets drag and drop events is a child of {@link DirectoryFragment#mRecView}. * {@link DragHoverListener} is used for both the scroll view and its children. * When we decide whether it's in the scroll zone we need to obtain the coordinate * relative to container view so we need to transform the coordinate if the view * that gets drag and drop events is a child of scroll view. */ private final Predicate<View> mIsScrollView; Loading Loading @@ -94,20 +95,37 @@ class DragHoverListener implements OnDragListener { mDragScroller = new ViewAutoScroller(scrollHost, scrollCallbacks); } static DragHoverListener create( public static DragHoverListener create( ItemDragListener<? extends DragHost> dragHandler, AbsListView scrollView) { return create(dragHandler, scrollView, scrollView::scrollListBy); } public static DragHoverListener create( ItemDragListener<? extends DragHost> dragHandler, View scrollView) { return create( dragHandler, scrollView, (int dy) -> { scrollView.scrollBy(0, dy); }); } static DragHoverListener create( ItemDragListener<? extends DragHost> dragHandler, View scrollView, IntConsumer scroller) { ScrollerCallbacks scrollCallbacks = new ScrollerCallbacks() { @Override public void scrollBy(int dy) { scrollView.scrollBy(0, dy); scroller.accept(dy); } @Override public void runAtNextFrame(Runnable r) { scrollView.postOnAnimation(r); } @Override Loading @@ -116,15 +134,13 @@ class DragHoverListener implements OnDragListener { } }; DragHoverListener listener = new DragHoverListener( return new DragHoverListener( dragHandler, scrollView::getHeight, (view) -> (scrollView == view), () -> scrollView.canScrollVertically(-1), () -> scrollView.canScrollVertically(1), scrollCallbacks); return listener; } @Override Loading Loading @@ -157,9 +173,9 @@ class DragHoverListener implements OnDragListener { } private Point transformToScrollViewCoordinate(View v, float x, float y) { // Check if v is the RecyclerView itself. If not we need to transform the coordinate to // relative to the RecyclerView because we need to test the scroll zone in the coordinate // relative to the RecyclerView; if yes we don't need to transform coordinates. // Check if v is the scroll view itself. If not we need to transform the coordinate to // relative to the scroll view because we need to test the scroll zone in the coordinate // relative to the scroll view; if yes we don't need to transform coordinates. final boolean isScrollView = mIsScrollView.test(v); final float offsetX = isScrollView ? 0 : v.getX(); final float offsetY = isScrollView ? 0 : v.getY(); Loading
src/com/android/documentsui/ItemDragListener.java +12 −0 Original line number Diff line number Diff line Loading @@ -63,6 +63,10 @@ public class ItemDragListener<H extends DragHost> implements OnDragListener { @Override public boolean onDrag(final View v, DragEvent event) { if (!mDragHost.canHandleDragEvent(v)) { return false; } switch (event.getAction()) { case DragEvent.ACTION_DRAG_STARTED: return true; Loading Loading @@ -193,5 +197,13 @@ public class ItemDragListener<H extends DragHost> implements OnDragListener { * Notifies when the drag and drop has ended. */ void onDragEnded(); /** * Whether drag events can dispatch to the view. * @param v the view being to receive drag events */ default boolean canHandleDragEvent(View v) { return true; } } }
src/com/android/documentsui/dirlist/DirectoryFragment.java +1 −0 Original line number Diff line number Diff line Loading @@ -64,6 +64,7 @@ import com.android.documentsui.ActionModeController; import com.android.documentsui.BaseActivity; import com.android.documentsui.BaseActivity.RetainedState; import com.android.documentsui.DocumentsApplication; import com.android.documentsui.DragHoverListener; import com.android.documentsui.FocusManager; import com.android.documentsui.Injector; import com.android.documentsui.Injector.ContentScoped; Loading
src/com/android/documentsui/sidebar/DragHost.java +5 −0 Original line number Diff line number Diff line Loading @@ -55,6 +55,11 @@ class DragHost extends AbstractDragHost { mActivity.runOnUiThread(runnable); } @Override public boolean canHandleDragEvent(View v) { return v instanceof RootItemView; } @Override public void setDropTargetHighlight(View v, boolean highlight) { // SpacerView doesn't have DragListener so this view is guaranteed to be a RootItemView. Loading
src/com/android/documentsui/sidebar/RootsFragment.java +4 −1 Original line number Diff line number Diff line Loading @@ -52,6 +52,7 @@ import android.widget.ListView; import com.android.documentsui.ActionHandler; import com.android.documentsui.BaseActivity; import com.android.documentsui.DocumentsApplication; import com.android.documentsui.DragHoverListener; import com.android.documentsui.Injector; import com.android.documentsui.Injector.Injected; import com.android.documentsui.ItemDragListener; Loading Loading @@ -197,7 +198,7 @@ public class RootsFragment extends Fragment { DocumentsApplication.getDragAndDropManager(activity), this::getItem, mActionHandler); mDragListener = new ItemDragListener<DragHost>(host) { final ItemDragListener<DragHost> listener = new ItemDragListener<DragHost>(host) { @Override public boolean handleDropEventChecked(View v, DragEvent event) { final Item item = getItem(v); Loading @@ -207,6 +208,8 @@ public class RootsFragment extends Fragment { return item.dropOn(event); } }; mDragListener = DragHoverListener.create(listener, mList); mList.setOnDragListener(mDragListener); } mCallbacks = new LoaderCallbacks<Collection<RootInfo>>() { Loading