Is there an example of how to use a TouchDelegate in Android to increase the size of a view's click target?

后端 未结 11 608
误落风尘
误落风尘 2020-11-28 19:01

My understanding is that when you have a view that\'s too small to easily touch, you\'re supposed to use a TouchDelegate to increase the clickable region for that view.

11条回答
  •  广开言路
    2020-11-28 19:17

    To expand the touch area generically with pretty few restrictions use the following code.

    It lets you expand the touch area of the given view within the given ancestor view by the given expansion in pixels. You can choose any ancestor as long as the given view is in the ancestors layout tree.

        public static void expandTouchArea(final View view, final ViewGroup ancestor, final int expansion) {
        ancestor.post(new Runnable() {
            public void run() {
                Rect bounds = getRelativeBounds(view, ancestor);
                Rect expandedBounds = expand(bounds, expansion);
                // LOG.debug("Expanding touch area of {} within {} from {} by {}px to {}", view, ancestor, bounds, expansion, expandedBounds);
                ancestor.setTouchDelegate(new TouchDelegate(expandedBounds, view));
            }
    
            private Rect getRelativeBounds(View view, ViewGroup ancestor) {
                Point relativeLocation = getRelativeLocation(view, ancestor);
                return new Rect(relativeLocation.x, relativeLocation.y,
                                relativeLocation.x + view.getWidth(),
                                relativeLocation.y + view.getHeight());
            }
    
            private Point getRelativeLocation(View view, ViewGroup ancestor) {
                Point absoluteAncestorLocation = getAbsoluteLocation(ancestor);
                Point absoluteViewLocation = getAbsoluteLocation(view);
                return new Point(absoluteViewLocation.x - absoluteAncestorLocation.x,
                                 absoluteViewLocation.y - absoluteAncestorLocation.y);
            }
    
            private Point getAbsoluteLocation(View view) {
                int[] absoluteLocation = new int[2];
                view.getLocationOnScreen(absoluteLocation);
                return new Point(absoluteLocation[0], absoluteLocation[1]);
            }
    
            private Rect expand(Rect rect, int by) {
                Rect expandedRect = new Rect(rect);
                expandedRect.left -= by;
                expandedRect.top -= by;
                expandedRect.right += by;
                expandedRect.bottom += by;
                return expandedRect;
            }
        });
    }
    

    Restrictions that apply:

    • The touch area can not exceed the bounds of the view's ancestor since the ancestor must be able to catch the touch event in order to forward it to the view.
    • Only one TouchDelegate can be set to a ViewGroup. If you want to work with multiple touch delegates, choose different ancestors or use a composing touch delegate like explained in How To Use Multiple TouchDelegate.

提交回复
热议问题