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 50 public UrlBarAutoShowManager(BaseUi ui) { 51 mUi = ui; 52 ViewConfiguration config = ViewConfiguration.get(mUi.getActivity()); 53 mSlop = config.getScaledTouchSlop() * 2; 54 } 55 56 public void setTarget(BrowserWebView v) { 57 if (mTarget == v) return; 58 59 if (mTarget != null) { 60 mTarget.setOnTouchListener(null); 61 mTarget.setOnScrollChangedListener(null); 62 } 63 mTarget = v; 64 if (mTarget != null) { 65 mTarget.setOnTouchListener(this); 66 mTarget.setOnScrollChangedListener(this); 67 } 68 } 69 70 @Override 71 public void onScrollChanged(int l, int t, int oldl, int oldt) { 72 mLastScrollTime = SystemClock.uptimeMillis(); 73 if (t != oldt) { 74 if (t != 0) { 75 // If it is showing, extend it 76 if (mUi.isTitleBarShowing()) { 77 long remaining = mLastScrollTime - mTriggeredTime; 78 remaining = Math.max(BaseUi.HIDE_TITLEBAR_DELAY - remaining, 79 SCROLL_TIMEOUT_DURATION); 80 mUi.showTitleBarForDuration(remaining); 81 } 82 } else { 83 mUi.suggestHideTitleBar(); 84 } 85 } 86 } 87 88 void stopTracking() { 89 if (mIsTracking) { 90 mIsTracking = false; 91 if (mUi.isTitleBarShowing()) { 92 mUi.showTitleBarForDuration(); 93 } 94 } 95 } 96 97 @Override 98 public boolean onTouch(View v, MotionEvent event) { 99 if (event.getPointerCount() > 1) { 100 stopTracking(); 101 } 102 switch (event.getAction()) { 103 case MotionEvent.ACTION_DOWN: 104 if (!mIsTracking && event.getPointerCount() == 1) { 105 long sinceLastScroll = 106 SystemClock.uptimeMillis() - mLastScrollTime; 107 if (sinceLastScroll < IGNORE_INTERVAL) { 108 break; 109 } 110 mStartTouchY = event.getY(); 111 mStartTouchX = event.getX(); 112 mIsTracking = true; 113 mHasTriggered = false; 114 } 115 break; 116 case MotionEvent.ACTION_MOVE: 117 if (mIsTracking && !mHasTriggered) { 118 WebView web = (WebView) v; 119 float dy = event.getY() - mStartTouchY; 120 float ady = Math.abs(dy); 121 float adx = Math.abs(event.getX() - mStartTouchX); 122 if (ady > mSlop) { 123 mHasTriggered = true; 124 float angle = (float) Math.atan2(ady, adx); 125 if (dy > mSlop && angle > V_TRIGGER_ANGLE 126 && !mUi.isTitleBarShowing() 127 && web.getVisibleTitleHeight() == 0) { 128 mTriggeredTime = SystemClock.uptimeMillis(); 129 mUi.showTitleBar(); 130 } 131 } 132 } 133 break; 134 case MotionEvent.ACTION_CANCEL: 135 case MotionEvent.ACTION_UP: 136 stopTracking(); 137 break; 138 } 139 return false; 140 } 141 142 } 143