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.graphics.PixelFormat; 21import android.os.Handler; 22import android.view.Gravity; 23import android.view.LayoutInflater; 24import android.view.View; 25import android.view.WindowManager; 26import android.widget.TextView; 27 28/** 29 * A on-screen hint is a view containing a little message for the user and will 30 * be shown on the screen continuously. This class helps you create and show 31 * those. 32 * 33 * <p> 34 * When the view is shown to the user, appears as a floating view over the 35 * application. 36 * <p> 37 * The easiest way to use this class is to call one of the static methods that 38 * constructs everything you need and returns a new {@code OnScreenHint} object. 39 */ 40public class OnScreenHint { 41 static final String TAG = "OnScreenHint"; 42 43 int mGravity = Gravity.CENTER_HORIZONTAL | Gravity.BOTTOM; 44 int mX, mY; 45 float mHorizontalMargin; 46 float mVerticalMargin; 47 View mView; 48 View mNextView; 49 50 private final WindowManager.LayoutParams mParams = 51 new WindowManager.LayoutParams(); 52 private final WindowManager mWM; 53 private final Handler mHandler = new Handler(); 54 55 /** 56 * Construct an empty OnScreenHint object. 57 * 58 * @param context The context to use. Usually your 59 * {@link android.app.Application} or 60 * {@link android.app.Activity} object. 61 */ 62 private OnScreenHint(Context context) { 63 mWM = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE); 64 mY = context.getResources().getDimensionPixelSize( 65 R.dimen.hint_y_offset); 66 67 mParams.height = WindowManager.LayoutParams.WRAP_CONTENT; 68 mParams.width = WindowManager.LayoutParams.WRAP_CONTENT; 69 mParams.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE 70 | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE; 71 mParams.format = PixelFormat.TRANSLUCENT; 72 mParams.windowAnimations = R.style.Animation_OnScreenHint; 73 mParams.type = WindowManager.LayoutParams.TYPE_APPLICATION_PANEL; 74 mParams.setTitle("OnScreenHint"); 75 } 76 77 /** 78 * Show the view on the screen. 79 */ 80 public void show() { 81 if (mNextView == null) { 82 throw new RuntimeException("View is not initialized"); 83 } 84 mHandler.post(mShow); 85 } 86 87 /** 88 * Close the view if it's showing. 89 */ 90 public void cancel() { 91 mHandler.post(mHide); 92 } 93 94 /** 95 * Make a standard hint that just contains a text view. 96 * 97 * @param context The context to use. Usually your 98 * {@link android.app.Application} or 99 * {@link android.app.Activity} object. 100 * @param text The text to show. Can be formatted text. 101 * 102 */ 103 public static OnScreenHint makeText(Context context, CharSequence text) { 104 OnScreenHint result = new OnScreenHint(context); 105 106 LayoutInflater inflate = 107 (LayoutInflater) context.getSystemService( 108 Context.LAYOUT_INFLATER_SERVICE); 109 View v = inflate.inflate(R.layout.on_screen_hint, null); 110 TextView tv = (TextView) v.findViewById(R.id.message); 111 tv.setText(text); 112 113 result.mNextView = v; 114 115 return result; 116 } 117 118 /** 119 * Update the text in a OnScreenHint that was previously created using one 120 * of the makeText() methods. 121 * @param s The new text for the OnScreenHint. 122 */ 123 public void setText(CharSequence s) { 124 if (mNextView == null) { 125 throw new RuntimeException("This OnScreenHint was not " 126 + "created with OnScreenHint.makeText()"); 127 } 128 TextView tv = (TextView) mNextView.findViewById(R.id.message); 129 if (tv == null) { 130 throw new RuntimeException("This OnScreenHint was not " 131 + "created with OnScreenHint.makeText()"); 132 } 133 tv.setText(s); 134 } 135 136 private synchronized void handleShow() { 137 if (mView != mNextView) { 138 // remove the old view if necessary 139 handleHide(); 140 mView = mNextView; 141 final int gravity = mGravity; 142 mParams.gravity = gravity; 143 if ((gravity & Gravity.HORIZONTAL_GRAVITY_MASK) 144 == Gravity.FILL_HORIZONTAL) { 145 mParams.horizontalWeight = 1.0f; 146 } 147 if ((gravity & Gravity.VERTICAL_GRAVITY_MASK) 148 == Gravity.FILL_VERTICAL) { 149 mParams.verticalWeight = 1.0f; 150 } 151 mParams.x = mX; 152 mParams.y = mY; 153 mParams.verticalMargin = mVerticalMargin; 154 mParams.horizontalMargin = mHorizontalMargin; 155 if (mView.getParent() != null) { 156 mWM.removeView(mView); 157 } 158 mWM.addView(mView, mParams); 159 } 160 } 161 162 private synchronized void handleHide() { 163 if (mView != null) { 164 // note: checking parent() just to make sure the view has 165 // been added... i have seen cases where we get here when 166 // the view isn't yet added, so let's try not to crash. 167 if (mView.getParent() != null) { 168 mWM.removeView(mView); 169 } 170 mView = null; 171 } 172 } 173 174 private final Runnable mShow = new Runnable() { 175 @Override 176 public void run() { 177 handleShow(); 178 } 179 }; 180 181 private final Runnable mHide = new Runnable() { 182 @Override 183 public void run() { 184 handleHide(); 185 } 186 }; 187} 188 189