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

Commit d0612e74 authored by Aurimas Liutikas's avatar Aurimas Liutikas Committed by Android (Google) Code Review
Browse files

Merge "Increase SearchView touch targets to meet GAR3." into nyc-dev

parents f94fcc3e c8fd00a0
Loading
Loading
Loading
Loading
+151 −1
Original line number Diff line number Diff line
@@ -53,7 +53,10 @@ import android.util.TypedValue;
import android.view.CollapsibleActionView;
import android.view.KeyEvent;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.TouchDelegate;
import android.view.View;
import android.view.ViewConfiguration;
import android.view.inputmethod.EditorInfo;
import android.view.inputmethod.InputMethodManager;
import android.widget.AdapterView.OnItemClickListener;
@@ -111,6 +114,12 @@ public class SearchView extends LinearLayout implements CollapsibleActionView {
    private final ImageView mVoiceButton;
    private final View mDropDownAnchor;

    private UpdatableTouchDelegate mTouchDelegate;
    private Rect mSearchSrcTextViewBounds = new Rect();
    private Rect mSearchSrtTextViewBoundsExpanded = new Rect();
    private int[] mTemp = new int[2];
    private int[] mTemp2 = new int[2];

    /** Icon optionally displayed when the SearchView is collapsed. */
    private final ImageView mCollapsedIcon;

@@ -801,7 +810,48 @@ public class SearchView extends LinearLayout implements CollapsibleActionView {
            break;
        }
        widthMode = MeasureSpec.EXACTLY;
        super.onMeasure(MeasureSpec.makeMeasureSpec(width, widthMode), heightMeasureSpec);

        int heightMode = MeasureSpec.getMode(heightMeasureSpec);
        int height = MeasureSpec.getSize(heightMeasureSpec);

        switch (heightMode) {
            case MeasureSpec.AT_MOST:
            case MeasureSpec.UNSPECIFIED:
                height = Math.min(getPreferredHeight(), height);
                break;
        }
        heightMode = MeasureSpec.EXACTLY;

        super.onMeasure(MeasureSpec.makeMeasureSpec(width, widthMode),
                MeasureSpec.makeMeasureSpec(height, heightMode));
    }

    @Override
    protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
        super.onLayout(changed, left, top, right, bottom);

        if (changed) {
            // Expand mSearchSrcTextView touch target to be the height of the parent in order to
            // allow it to be up to 48dp.
            getChildBoundsWithinSearchView(mSearchSrcTextView, mSearchSrcTextViewBounds);
            mSearchSrtTextViewBoundsExpanded.set(
                    mSearchSrcTextViewBounds.left, 0, mSearchSrcTextViewBounds.right, bottom - top);
            if (mTouchDelegate == null) {
                mTouchDelegate = new UpdatableTouchDelegate(mSearchSrtTextViewBoundsExpanded,
                        mSearchSrcTextViewBounds, mSearchSrcTextView);
                setTouchDelegate(mTouchDelegate);
            } else {
                mTouchDelegate.setBounds(mSearchSrtTextViewBoundsExpanded, mSearchSrcTextViewBounds);
            }
        }
    }

    private void getChildBoundsWithinSearchView(View view, Rect rect) {
        view.getLocationInWindow(mTemp);
        getLocationInWindow(mTemp2);
        final int top = mTemp[1] - mTemp2[1];
        final int left = mTemp[0] - mTemp2[0];
        rect.set(left , top, left + view.getWidth(), top + view.getHeight());
    }

    private int getPreferredWidth() {
@@ -809,6 +859,11 @@ public class SearchView extends LinearLayout implements CollapsibleActionView {
                .getDimensionPixelSize(R.dimen.search_view_preferred_width);
    }

    private int getPreferredHeight() {
        return getContext().getResources()
                .getDimensionPixelSize(R.dimen.search_view_preferred_height);
    }

    private void updateViewsVisibility(final boolean collapsed) {
        mIconified = collapsed;
        // Visibility of views that are visible when collapsed
@@ -1749,6 +1804,101 @@ public class SearchView extends LinearLayout implements CollapsibleActionView {
        }
    };

    private static class UpdatableTouchDelegate extends TouchDelegate {
        /**
         * View that should receive forwarded touch events
         */
        private final View mDelegateView;

        /**
         * Bounds in local coordinates of the containing view that should be mapped to the delegate
         * view. This rect is used for initial hit testing.
         */
        private final Rect mTargetBounds;

        /**
         * Bounds in local coordinates of the containing view that are actual bounds of the delegate
         * view. This rect is used for event coordinate mapping.
         */
        private final Rect mActualBounds;

        /**
         * mTargetBounds inflated to include some slop. This rect is to track whether the motion events
         * should be considered to be be within the delegate view.
         */
        private final Rect mSlopBounds;

        private final int mSlop;

        /**
         * True if the delegate had been targeted on a down event (intersected mTargetBounds).
         */
        private boolean mDelegateTargeted;

        public UpdatableTouchDelegate(Rect targetBounds, Rect actualBounds, View delegateView) {
            super(targetBounds, delegateView);
            mSlop = ViewConfiguration.get(delegateView.getContext()).getScaledTouchSlop();
            mTargetBounds = new Rect();
            mSlopBounds = new Rect();
            mActualBounds = new Rect();
            setBounds(targetBounds, actualBounds);
            mDelegateView = delegateView;
        }

        public void setBounds(Rect desiredBounds, Rect actualBounds) {
            mTargetBounds.set(desiredBounds);
            mSlopBounds.set(desiredBounds);
            mSlopBounds.inset(-mSlop, -mSlop);
            mActualBounds.set(actualBounds);
        }

        @Override
        public boolean onTouchEvent(MotionEvent event) {
            final int x = (int) event.getX();
            final int y = (int) event.getY();
            boolean sendToDelegate = false;
            boolean hit = true;
            boolean handled = false;

            switch (event.getAction()) {
                case MotionEvent.ACTION_DOWN:
                    if (mTargetBounds.contains(x, y)) {
                        mDelegateTargeted = true;
                        sendToDelegate = true;
                    }
                    break;
                case MotionEvent.ACTION_UP:
                case MotionEvent.ACTION_MOVE:
                    sendToDelegate = mDelegateTargeted;
                    if (sendToDelegate) {
                        if (!mSlopBounds.contains(x, y)) {
                            hit = false;
                        }
                    }
                    break;
                case MotionEvent.ACTION_CANCEL:
                    sendToDelegate = mDelegateTargeted;
                    mDelegateTargeted = false;
                    break;
            }
            if (sendToDelegate) {
                if (hit && !mActualBounds.contains(x, y)) {
                    // Offset event coordinates to be in the center of the target view since we
                    // are within the targetBounds, but not inside the actual bounds of
                    // mDelegateView
                    event.setLocation(mDelegateView.getWidth() / 2,
                            mDelegateView.getHeight() / 2);
                } else {
                    // Offset event coordinates to the target view coordinates.
                    event.setLocation(x - mActualBounds.left, y - mActualBounds.top);
                }

                handled = mDelegateView.dispatchTouchEvent(event);
            }
            return handled;
        }
    }

    /**
     * Local subclass for AutoCompleteTextView.
     * @hide
+3 −6
Original line number Diff line number Diff line
@@ -48,11 +48,8 @@
    <LinearLayout
        android:id="@+id/search_edit_frame"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_height="match_parent"
        android:layout_weight="1"
        android:layout_gravity="center_vertical"
        android:layout_marginTop="4dip"
        android:layout_marginBottom="4dip"
        android:layout_marginStart="8dip"
        android:layout_marginEnd="8dip"
        android:orientation="horizontal"
@@ -71,7 +68,7 @@
        <LinearLayout
            android:id="@+id/search_plate"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_height="match_parent"
            android:layout_weight="1"
            android:layout_gravity="center_vertical"
            android:orientation="horizontal">
@@ -81,7 +78,7 @@
                android:layout_height="36dip"
                android:layout_width="0dp"
                android:layout_weight="1"
                android:layout_gravity="bottom"
                android:layout_gravity="center_vertical"
                android:paddingStart="@dimen/dropdownitem_text_padding_left"
                android:paddingEnd="@dimen/dropdownitem_text_padding_right"
                android:singleLine="true"
+2 −1
Original line number Diff line number Diff line
@@ -184,8 +184,9 @@
    <!-- The spacing between messages in Notification.MessagingStyle -->
    <dimen name="notification_messaging_spacing">6dp</dimen>

    <!-- Preferred width of the search view. -->
    <!-- Preferred width and height of the search view. -->
    <dimen name="search_view_preferred_width">320dip</dimen>
    <dimen name="search_view_preferred_height">48dip</dimen>

    <!-- Dialog padding for round display -->
    <dimen name="alert_dialog_round_padding">27dip</dimen>
+1 −0
Original line number Diff line number Diff line
@@ -423,6 +423,7 @@
  <java-symbol type="dimen" name="dropdownitem_text_padding_left" />
  <java-symbol type="dimen" name="password_keyboard_spacebar_vertical_correction" />
  <java-symbol type="dimen" name="search_view_preferred_width" />
  <java-symbol type="dimen" name="search_view_preferred_height" />
  <java-symbol type="dimen" name="textview_error_popup_default_width" />
  <java-symbol type="dimen" name="toast_y_offset" />
  <java-symbol type="dimen" name="action_bar_stacked_max_height" />