Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 056556dd authored by Ben Lin's avatar Ben Lin Committed by android-build-merger
Browse files

Fix Gesture Select bug when user is in RTL mode.

am: abbb6e0b

Change-Id: I9403844368c968f229e5972117faef088746cfd2
parents 7c5ecbc8 abbb6e0b
Loading
Loading
Loading
Loading
+23 −3
Original line number Diff line number Diff line
@@ -17,6 +17,7 @@
package com.android.documentsui.dirlist;

import android.graphics.Point;
import android.support.annotation.VisibleForTesting;
import android.support.v7.widget.RecyclerView;
import android.view.MotionEvent;
import android.view.View;
@@ -189,7 +190,12 @@ final class GestureSelector {
            // last item of the recycler view), we would want to set that as the currentItemPos
            View lastItem = rv.getLayoutManager()
                    .getChildAt(rv.getLayoutManager().getChildCount() - 1);
            boolean bottomRight = e.getX() > lastItem.getRight() && e.getY() > lastItem.getTop();
            int direction = rv.getContext().getResources().getConfiguration().getLayoutDirection();
            final boolean pastLastItem = isPastLastItem(lastItem.getTop(),
                    lastItem.getLeft(),
                    lastItem.getRight(),
                    event,
                    direction);

            // Since views get attached & detached from RecyclerView,
            // {@link LayoutManager#getChildCount} can return a different number from the actual
@@ -197,7 +203,7 @@ final class GestureSelector {
            // of items in the adapter. Using the adapter is the for sure way to get the actual last
            // item position.
            final float inboundY = getInboundY(rv.getHeight(), e.getY());
            final int lastGlidedItemPos = (bottomRight) ? rv.getAdapter().getItemCount() - 1
            final int lastGlidedItemPos = (pastLastItem) ? rv.getAdapter().getItemCount() - 1
                    : rv.getChildAdapterPosition(rv.findChildViewUnder(e.getX(), inboundY));
            if (lastGlidedItemPos != RecyclerView.NO_POSITION) {
                doGestureMultiSelect(lastGlidedItemPos);
@@ -211,7 +217,7 @@ final class GestureSelector {
    // It's possible for events to go over the top/bottom of the RecyclerView.
    // We want to get a Y-coordinate within the RecyclerView so we can find the childView underneath
    // correctly.
    private float getInboundY(float max, float y) {
    private static float getInboundY(float max, float y) {
        if (y < 0f) {
            return 0f;
        } else if (y > max) {
@@ -220,6 +226,20 @@ final class GestureSelector {
        return y;
    }

    /*
     * Check to see an InputEvent if past a particular item, i.e. to the right or to the bottom
     * of the item.
     * For RTL, it would to be to the left or to the bottom of the item.
     */
    @VisibleForTesting
    static boolean isPastLastItem(int top, int left, int right, InputEvent e, int direction) {
        if (direction == View.LAYOUT_DIRECTION_LTR) {
            return e.getX() > right && e.getY() > top;
        } else {
            return e.getX() < left && e.getY() > top;
        }
    }

    /* Given the end position, select everything in-between.
     * @param endPos  The adapter position of the end item.
     */
+65 −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.graphics.Point;
import android.test.AndroidTestCase;
import android.test.suitebuilder.annotation.SmallTest;
import android.view.View;

import com.android.documentsui.TestInputEvent;

@SmallTest
public class GestureSelectorTest extends AndroidTestCase {

    TestInputEvent e;

    // Simulate a (20, 20) box locating at (20, 20)
    static final int LEFT_BORDER = 20;
    static final int RIGHT_BORDER = 40;
    static final int TOP_BORDER = 20;
    static final int BOTTOM_BORDER = 40;

    @Override
    public void setUp() throws Exception {
        e = new TestInputEvent();
    }

    public void testLTRPastLastItem() {
        e.location = new Point(100, 100);
        assertTrue(GestureSelector.isPastLastItem(
                TOP_BORDER, LEFT_BORDER, RIGHT_BORDER, e, View.LAYOUT_DIRECTION_LTR));
    }

    public void testLTRPastLastItem_Inverse() {
        e.location = new Point(10, 10);
        assertFalse(GestureSelector.isPastLastItem(
                TOP_BORDER, LEFT_BORDER, RIGHT_BORDER, e, View.LAYOUT_DIRECTION_LTR));
    }

    public void testRTLPastLastItem() {
        e.location = new Point(10, 30);
        assertTrue(GestureSelector.isPastLastItem(
                TOP_BORDER, LEFT_BORDER, RIGHT_BORDER, e, View.LAYOUT_DIRECTION_RTL));
    }

    public void testRTLPastLastItem_Inverse() {
        e.location = new Point(100, 100);
        assertFalse(GestureSelector.isPastLastItem(
                TOP_BORDER, LEFT_BORDER, RIGHT_BORDER, e, View.LAYOUT_DIRECTION_RTL));
    }
}