OnScreenHint.java revision bbc560b5216bbb2e3028020e426ce6a6e0e5df08
1/* 2 * Copyright (C) 2009 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.camera; 18 19import android.content.Context; 20import android.content.res.Resources; 21import android.graphics.PixelFormat; 22import android.os.Handler; 23import android.view.Gravity; 24import android.view.LayoutInflater; 25import android.view.View; 26import android.view.WindowManager; 27import android.widget.TextView; 28 29/** 30 * A on-screen hint is a view containing a little message for the user and will 31 * be shown on the screen continuously. This class helps you create and show 32 * those. 33 * 34 * <p> 35 * When the view is shown to the user, appears as a floating view over the 36 * application. 37 * <p> 38 * The easiest way to use this class is to call one of the static methods that 39 * constructs everything you need and returns a new OnScreenHint object. 40 */ 41public class OnScreenHint { 42 static final String TAG = "OnScreenHint"; 43 static final boolean LOCAL_LOGV = false; 44 45 final Context mContext; 46 int mGravity = Gravity.CENTER_HORIZONTAL | Gravity.BOTTOM; 47 int mX, mY; 48 float mHorizontalMargin; 49 float mVerticalMargin; 50 View mView; 51 View mNextView; 52 53 private final WindowManager.LayoutParams mParams = 54 new WindowManager.LayoutParams(); 55 private final WindowManager mWM; 56 private final Handler mHandler = new Handler(); 57 58 /** 59 * Construct an empty OnScreenHint object. You must call {@link #setView} 60 * before you can call {@link #show}. 61 * 62 * @param context The context to use. Usually your 63 * {@link android.app.Application} or 64 * {@link android.app.Activity} object. 65 */ 66 public OnScreenHint(Context context) { 67 mContext = context; 68 mWM = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE); 69 mY = context.getResources().getDimensionPixelSize( 70 R.dimen.hint_y_offset); 71 72 mParams.height = WindowManager.LayoutParams.WRAP_CONTENT; 73 mParams.width = WindowManager.LayoutParams.WRAP_CONTENT; 74 mParams.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE 75 | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE; 76 mParams.format = PixelFormat.TRANSLUCENT; 77 mParams.windowAnimations = R.style.Animation_OnScreenHint; 78 mParams.type = WindowManager.LayoutParams.TYPE_APPLICATION_PANEL; 79 mParams.setTitle("OnScreenHint"); 80 } 81 82 /** 83 * Show the view on the screen. 84 */ 85 public void show() { 86 if (mNextView == null) { 87 throw new RuntimeException("setView must have been called"); 88 } 89 mHandler.post(mShow); 90 } 91 92 /** 93 * Close the view if it's showing. 94 */ 95 public void cancel() { 96 mHandler.post(mHide); 97 } 98 99 /** 100 * Set the view to show. 101 * @see #getView 102 */ 103 public void setView(View view) { 104 mNextView = view; 105 } 106 107 /** 108 * Return the view. 109 * @see #setView 110 */ 111 public View getView() { 112 return mNextView; 113 } 114 115 /** 116 * Set the margins of the view. 117 * 118 * @param horizontalMargin The horizontal margin, in percentage of the 119 * container width, between the container's edges and the 120 * notification 121 * @param verticalMargin The vertical margin, in percentage of the 122 * container height, between the container's edges and the 123 * notification 124 */ 125 public void setMargin(float horizontalMargin, float verticalMargin) { 126 mHorizontalMargin = horizontalMargin; 127 mVerticalMargin = verticalMargin; 128 } 129 130 /** 131 * Return the horizontal margin. 132 */ 133 public float getHorizontalMargin() { 134 return mHorizontalMargin; 135 } 136 137 /** 138 * Return the vertical margin. 139 */ 140 public float getVerticalMargin() { 141 return mVerticalMargin; 142 } 143 144 /** 145 * Set the location at which the notification should appear on the screen. 146 * @see android.view.Gravity 147 * @see #getGravity 148 */ 149 public void setGravity(int gravity, int xOffset, int yOffset) { 150 mGravity = gravity; 151 mX = xOffset; 152 mY = yOffset; 153 } 154 155 /** 156 * Get the location at which the notification should appear on the screen. 157 * @see android.view.Gravity 158 * @see #getGravity 159 */ 160 public int getGravity() { 161 return mGravity; 162 } 163 164 /** 165 * Return the X offset in pixels to apply to the gravity's location. 166 */ 167 public int getXOffset() { 168 return mX; 169 } 170 171 /** 172 * Return the Y offset in pixels to apply to the gravity's location. 173 */ 174 public int getYOffset() { 175 return mY; 176 } 177 178 /** 179 * Make a standard hint that just contains a text view. 180 * 181 * @param context The context to use. Usually your 182 * {@link android.app.Application} or 183 * {@link android.app.Activity} object. 184 * @param text The text to show. Can be formatted text. 185 * 186 */ 187 public static OnScreenHint makeText(Context context, CharSequence text) { 188 OnScreenHint result = new OnScreenHint(context); 189 190 LayoutInflater inflate = 191 (LayoutInflater) context.getSystemService( 192 Context.LAYOUT_INFLATER_SERVICE); 193 View v = inflate.inflate(R.layout.on_screen_hint, null); 194 TextView tv = (TextView) v.findViewById(R.id.message); 195 tv.setText(text); 196 197 result.mNextView = v; 198 199 return result; 200 } 201 202 /** 203 * Make a standard hint that just contains a text view with the text from a 204 * resource. 205 * 206 * @param context The context to use. Usually your 207 * {@link android.app.Application} or 208 * {@link android.app.Activity} object. 209 * @param resId The resource id of the string resource to use. Can be 210 * formatted text. 211 * 212 * @throws Resources.NotFoundException if the resource can't be found. 213 */ 214 public static OnScreenHint makeText(Context context, int resId) 215 throws Resources.NotFoundException { 216 return makeText(context, context.getResources().getText(resId)); 217 } 218 219 /** 220 * Update the text in a OnScreenHint that was previously created using one 221 * of the makeText() methods. 222 * @param resId The new text for the OnScreenHint. 223 */ 224 public void setText(int resId) { 225 setText(mContext.getText(resId)); 226 } 227 228 /** 229 * Update the text in a OnScreenHint that was previously created using one 230 * of the makeText() methods. 231 * @param s The new text for the OnScreenHint. 232 */ 233 public void setText(CharSequence s) { 234 if (mNextView == null) { 235 throw new RuntimeException("This OnScreenHint was not " 236 + "created with OnScreenHint.makeText()"); 237 } 238 TextView tv = (TextView) mNextView.findViewById(R.id.message); 239 if (tv == null) { 240 throw new RuntimeException("This OnScreenHint was not " 241 + "created with OnScreenHint.makeText()"); 242 } 243 tv.setText(s); 244 } 245 246 private synchronized void handleShow() { 247 if (mView != mNextView) { 248 // remove the old view if necessary 249 handleHide(); 250 mView = mNextView; 251 final int gravity = mGravity; 252 mParams.gravity = gravity; 253 if ((gravity & Gravity.HORIZONTAL_GRAVITY_MASK) 254 == Gravity.FILL_HORIZONTAL) { 255 mParams.horizontalWeight = 1.0f; 256 } 257 if ((gravity & Gravity.VERTICAL_GRAVITY_MASK) 258 == Gravity.FILL_VERTICAL) { 259 mParams.verticalWeight = 1.0f; 260 } 261 mParams.x = mX; 262 mParams.y = mY; 263 mParams.verticalMargin = mVerticalMargin; 264 mParams.horizontalMargin = mHorizontalMargin; 265 if (mView.getParent() != null) { 266 mWM.removeView(mView); 267 } 268 mWM.addView(mView, mParams); 269 } 270 } 271 272 private synchronized void handleHide() { 273 if (mView != null) { 274 // note: checking parent() just to make sure the view has 275 // been added... i have seen cases where we get here when 276 // the view isn't yet added, so let's try not to crash. 277 if (mView.getParent() != null) { 278 mWM.removeView(mView); 279 } 280 mView = null; 281 } 282 } 283 284 private final Runnable mShow = new Runnable() { 285 public void run() { 286 handleShow(); 287 } 288 }; 289 290 private final Runnable mHide = new Runnable() { 291 public void run() { 292 handleHide(); 293 } 294 }; 295} 296 297