• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2018 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package com.google.android.setupdesign.view;
18 
19 import android.text.Selection;
20 import android.text.Spannable;
21 import android.text.method.LinkMovementMethod;
22 import android.text.method.MovementMethod;
23 import android.view.MotionEvent;
24 import android.widget.TextView;
25 
26 /**
27  * A movement method that tracks the last result of whether touch events are handled. This is used
28  * to patch the return value of {@link TextView#onTouchEvent} so that it consumes the touch events
29  * only when the movement method says the event is consumed.
30  */
31 public interface TouchableMovementMethod {
32 
33   /** @return The last touch event received in {@link MovementMethod#onTouchEvent} */
getLastTouchEvent()34   MotionEvent getLastTouchEvent();
35 
36   /**
37    * @return The return value of the last {@link MovementMethod#onTouchEvent}, or whether the last
38    *     touch event should be considered handled by the text view
39    */
isLastTouchEventHandled()40   boolean isLastTouchEventHandled();
41 
42   /**
43    * An extension of LinkMovementMethod that tracks whether the event is handled when it is touched.
44    */
45   class TouchableLinkMovementMethod extends LinkMovementMethod implements TouchableMovementMethod {
46 
getInstance()47     public static TouchableLinkMovementMethod getInstance() {
48       return new TouchableLinkMovementMethod();
49     }
50 
51     boolean lastEventResult = false;
52     MotionEvent lastEvent;
53 
54     @Override
onTouchEvent(TextView widget, Spannable buffer, MotionEvent event)55     public boolean onTouchEvent(TextView widget, Spannable buffer, MotionEvent event) {
56       lastEvent = event;
57       boolean result = super.onTouchEvent(widget, buffer, event);
58       if (event.getAction() == MotionEvent.ACTION_DOWN) {
59         // Unfortunately, LinkMovementMethod extends ScrollMovementMethod, and it always
60         // consume the down event. So here we use the selection instead as a hint of whether
61         // the down event landed on a link.
62         lastEventResult = Selection.getSelectionStart(buffer) != -1;
63       } else {
64         lastEventResult = result;
65       }
66       return result;
67     }
68 
69     @Override
getLastTouchEvent()70     public MotionEvent getLastTouchEvent() {
71       return lastEvent;
72     }
73 
74     @Override
isLastTouchEventHandled()75     public boolean isLastTouchEventHandled() {
76       return lastEventResult;
77     }
78   }
79 }
80