1 /** 2 * Copyright (C) 2014 Google Inc. 3 * Licensed to The Android Open Source Project. 4 * 5 * Licensed under the Apache License, Version 2.0 (the "License"); 6 * you may not use this file except in compliance with the License. 7 * You may obtain a copy of the License at 8 * 9 * http://www.apache.org/licenses/LICENSE-2.0 10 * 11 * Unless required by applicable law or agreed to in writing, software 12 * distributed under the License is distributed on an "AS IS" BASIS, 13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 * See the License for the specific language governing permissions and 15 * limitations under the License. 16 */ 17 package com.android.mail.ui; 18 19 import android.content.Context; 20 import android.os.SystemClock; 21 import androidx.annotation.NonNull; 22 import android.util.AttributeSet; 23 import android.view.MotionEvent; 24 import android.view.ViewConfiguration; 25 import android.widget.FrameLayout; 26 27 /** 28 * Empty frame to steal events for two-pane view when the drawer is open. 29 */ 30 public class ConversationViewFrame extends FrameLayout { 31 32 private final ViewConfiguration mConfiguration; 33 private long mInterceptedTime; 34 private float mInterceptedXDown; 35 private float mInterceptedYDown; 36 37 public interface DownEventListener { shouldBlockTouchEvents()38 boolean shouldBlockTouchEvents(); onConversationViewFrameTapped()39 void onConversationViewFrameTapped(); onConversationViewTouchDown()40 void onConversationViewTouchDown(); 41 } 42 43 private DownEventListener mDownEventListener; 44 ConversationViewFrame(Context c)45 public ConversationViewFrame(Context c) { 46 this(c, null); 47 } 48 ConversationViewFrame(Context c, AttributeSet attrs)49 public ConversationViewFrame(Context c, AttributeSet attrs) { 50 super(c, attrs); 51 mConfiguration = ViewConfiguration.get(c); 52 } 53 setDownEventListener(DownEventListener l)54 public void setDownEventListener(DownEventListener l) { 55 mDownEventListener = l; 56 } 57 58 @Override onInterceptTouchEvent(MotionEvent ev)59 public boolean onInterceptTouchEvent(MotionEvent ev) { 60 final boolean steal = (mDownEventListener != null 61 && mDownEventListener.shouldBlockTouchEvents()); 62 if (!steal && ev.getActionMasked() == MotionEvent.ACTION_DOWN 63 && mDownEventListener != null) { 64 // notify 2-pane that this CV is being interacted (to turn a peek->normal) 65 mDownEventListener.onConversationViewTouchDown(); 66 } 67 return steal; 68 } 69 70 @Override onTouchEvent(@onNull MotionEvent ev)71 public boolean onTouchEvent(@NonNull MotionEvent ev) { 72 if (mDownEventListener != null) { 73 switch (ev.getActionMasked()) { 74 case MotionEvent.ACTION_DOWN: 75 mInterceptedTime = SystemClock.elapsedRealtime(); 76 mInterceptedXDown = ev.getX(); 77 mInterceptedYDown = ev.getY(); 78 break; 79 case MotionEvent.ACTION_UP: 80 // Check for a tap 81 final long timeDelta = SystemClock.elapsedRealtime() - mInterceptedTime; 82 final float xDelta = ev.getX() - mInterceptedXDown; 83 final float yDelta = ev.getY() - mInterceptedYDown; 84 if (timeDelta < ViewConfiguration.getTapTimeout() 85 && xDelta < mConfiguration.getScaledTouchSlop() 86 && yDelta < mConfiguration.getScaledTouchSlop()) { 87 mDownEventListener.onConversationViewFrameTapped(); 88 } 89 } 90 return true; 91 } 92 return false; 93 } 94 95 } 96