1 /* 2 * Copyright (C) 2011 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 package com.android.browser; 17 18 import android.os.SystemClock; 19 import android.view.MotionEvent; 20 import android.view.View; 21 import android.view.View.OnTouchListener; 22 import android.view.ViewConfiguration; 23 import android.webkit.WebView; 24 25 import com.android.browser.BrowserWebView.OnScrollChangedListener; 26 27 /** 28 * Helper class to manage when to show the URL bar based off of touch 29 * input, and when to begin the hide timer. 30 */ 31 public class UrlBarAutoShowManager implements OnTouchListener, 32 OnScrollChangedListener { 33 34 private static float V_TRIGGER_ANGLE = .9f; 35 private static long SCROLL_TIMEOUT_DURATION = 150; 36 private static long IGNORE_INTERVAL = 250; 37 38 private BrowserWebView mTarget; 39 private BaseUi mUi; 40 41 private int mSlop; 42 43 private float mStartTouchX; 44 private float mStartTouchY; 45 private boolean mIsTracking; 46 private boolean mHasTriggered; 47 private long mLastScrollTime; 48 private long mTriggeredTime; 49 private boolean mIsScrolling; 50 UrlBarAutoShowManager(BaseUi ui)51 public UrlBarAutoShowManager(BaseUi ui) { 52 mUi = ui; 53 ViewConfiguration config = ViewConfiguration.get(mUi.getActivity()); 54 mSlop = config.getScaledTouchSlop() * 2; 55 } 56 setTarget(BrowserWebView v)57 public void setTarget(BrowserWebView v) { 58 if (mTarget == v) return; 59 60 if (mTarget != null) { 61 mTarget.setOnTouchListener(null); 62 mTarget.setOnScrollChangedListener(null); 63 } 64 mTarget = v; 65 if (mTarget != null) { 66 mTarget.setOnTouchListener(this); 67 mTarget.setOnScrollChangedListener(this); 68 } 69 } 70 71 @Override onScrollChanged(int l, int t, int oldl, int oldt)72 public void onScrollChanged(int l, int t, int oldl, int oldt) { 73 mLastScrollTime = SystemClock.uptimeMillis(); 74 mIsScrolling = true; 75 if (t != 0) { 76 // If it is showing, extend it 77 if (mUi.isTitleBarShowing()) { 78 long remaining = mLastScrollTime - mTriggeredTime; 79 remaining = Math.max(BaseUi.HIDE_TITLEBAR_DELAY - remaining, 80 SCROLL_TIMEOUT_DURATION); 81 mUi.showTitleBarForDuration(remaining); 82 } 83 } else { 84 mUi.suggestHideTitleBar(); 85 } 86 } 87 stopTracking()88 void stopTracking() { 89 if (mIsTracking) { 90 mIsTracking = false; 91 mIsScrolling = false; 92 if (mUi.isTitleBarShowing()) { 93 mUi.showTitleBarForDuration(); 94 } 95 } 96 } 97 98 @Override onTouch(View v, MotionEvent event)99 public boolean onTouch(View v, MotionEvent event) { 100 if (event.getPointerCount() > 1) { 101 stopTracking(); 102 } 103 switch (event.getAction()) { 104 case MotionEvent.ACTION_DOWN: 105 if (!mIsTracking && event.getPointerCount() == 1) { 106 long sinceLastScroll = 107 SystemClock.uptimeMillis() - mLastScrollTime; 108 if (sinceLastScroll < IGNORE_INTERVAL) { 109 break; 110 } 111 mStartTouchY = event.getY(); 112 mStartTouchX = event.getX(); 113 mIsTracking = true; 114 mHasTriggered = false; 115 } 116 break; 117 case MotionEvent.ACTION_MOVE: 118 if (mIsTracking && !mHasTriggered) { 119 WebView web = (WebView) v; 120 float dy = event.getY() - mStartTouchY; 121 float ady = Math.abs(dy); 122 float adx = Math.abs(event.getX() - mStartTouchX); 123 if (ady > mSlop) { 124 mHasTriggered = true; 125 float angle = (float) Math.atan2(ady, adx); 126 if (dy > mSlop && angle > V_TRIGGER_ANGLE 127 && !mUi.isTitleBarShowing() 128 && (web.getVisibleTitleHeight() == 0 129 || (!mIsScrolling && web.getScrollY() > 0))) { 130 mTriggeredTime = SystemClock.uptimeMillis(); 131 mUi.showTitleBar(); 132 } 133 } 134 } 135 break; 136 case MotionEvent.ACTION_CANCEL: 137 case MotionEvent.ACTION_UP: 138 stopTracking(); 139 break; 140 } 141 return false; 142 } 143 144 } 145