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 17package com.android.setupwizardlib.view; 18 19import android.text.Selection; 20import android.text.Spannable; 21import android.text.method.LinkMovementMethod; 22import android.text.method.MovementMethod; 23import android.view.MotionEvent; 24import android.widget.TextView; 25 26/** 27 * A movement method that tracks the last result of whether touch events are handled. This is 28 * used to patch the return value of {@link TextView#onTouchEvent} so that it consumes the touch 29 * events only when the movement method says the event is consumed. 30 */ 31public interface TouchableMovementMethod { 32 33 /** 34 * @return The last touch event received in {@link MovementMethod#onTouchEvent} 35 */ 36 MotionEvent getLastTouchEvent(); 37 38 /** 39 * @return The return value of the last {@link MovementMethod#onTouchEvent}, or whether the 40 * last touch event should be considered handled by the text view 41 */ 42 boolean isLastTouchEventHandled(); 43 44 /** 45 * An extension of LinkMovementMethod that tracks whether the event is handled when it is 46 * touched. 47 */ 48 class TouchableLinkMovementMethod extends LinkMovementMethod 49 implements TouchableMovementMethod { 50 51 public static TouchableLinkMovementMethod getInstance() { 52 return new TouchableLinkMovementMethod(); 53 } 54 55 boolean mLastEventResult = false; 56 MotionEvent mLastEvent; 57 58 @Override 59 public boolean onTouchEvent(TextView widget, Spannable buffer, MotionEvent event) { 60 mLastEvent = event; 61 boolean result = super.onTouchEvent(widget, buffer, event); 62 if (event.getAction() == MotionEvent.ACTION_DOWN) { 63 // Unfortunately, LinkMovementMethod extends ScrollMovementMethod, and it always 64 // consume the down event. So here we use the selection instead as a hint of whether 65 // the down event landed on a link. 66 mLastEventResult = Selection.getSelectionStart(buffer) != -1; 67 } else { 68 mLastEventResult = result; 69 } 70 return result; 71 } 72 73 @Override 74 public MotionEvent getLastTouchEvent() { 75 return mLastEvent; 76 } 77 78 @Override 79 public boolean isLastTouchEventHandled() { 80 return mLastEventResult; 81 } 82 } 83} 84