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 17 package com.android.camera; 18 19 import android.app.Activity; 20 import android.content.Context; 21 import android.graphics.PixelFormat; 22 import android.os.Handler; 23 import android.view.LayoutInflater; 24 import android.view.View; 25 import android.view.WindowManager; 26 import android.widget.TextView; 27 28 import com.android.camera.debug.Log; 29 import com.android.camera.util.AndroidServices; 30 import com.android.camera2.R; 31 32 /** 33 * A on-screen hint is a view containing a little message for the user and will 34 * be shown on the screen continuously. This class helps you create and show 35 * those. 36 * 37 * <p> 38 * When the view is shown to the user, appears as a floating view over the 39 * application. 40 * <p> 41 * The easiest way to use this class is to call one of the static methods that 42 * constructs everything you need and returns a new {@code OnScreenHint} object. 43 */ 44 public class OnScreenHint { 45 static final Log.Tag TAG = new Log.Tag("OnScreenHint"); 46 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 activity An activity from which to create a {@link WindowManager} 59 * to create and attach a view. This must be an Activity, not an 60 * application context, otherwise app will crash upon display of the 61 * hint due to adding a view to a application {@link WindowManager} 62 * that doesn't allow view attachment. 63 */ OnScreenHint(Activity activity)64 private OnScreenHint(Activity activity) { 65 mWM = (WindowManager) activity.getSystemService(Context.WINDOW_SERVICE); 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 */ show()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 */ cancel()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 activity An activity from which to create a {@link WindowManager} 98 * to create and attach a view. This must be an Activity, not an 99 * application context, otherwise app will crash upon display of the 100 * hint due to adding a view to a application {@link WindowManager} 101 * that doesn't allow view attachment. 102 * @param text The text to show. Can be formatted text. 103 * 104 */ makeText(Activity activity, CharSequence text)105 public static OnScreenHint makeText(Activity activity, CharSequence text) { 106 OnScreenHint result = new OnScreenHint(activity); 107 108 LayoutInflater inflate = (LayoutInflater) activity.getSystemService( 109 Context.LAYOUT_INFLATER_SERVICE); 110 View v = inflate.inflate(R.layout.on_screen_hint, null); 111 TextView tv = (TextView) v.findViewById(R.id.message); 112 tv.setText(text); 113 114 result.mNextView = v; 115 116 return result; 117 } 118 119 /** 120 * Update the text in a OnScreenHint that was previously created using one 121 * of the makeText() methods. 122 * @param s The new text for the OnScreenHint. 123 */ setText(CharSequence s)124 public void setText(CharSequence s) { 125 if (mNextView == null) { 126 throw new RuntimeException("This OnScreenHint was not " 127 + "created with OnScreenHint.makeText()"); 128 } 129 TextView tv = (TextView) mNextView.findViewById(R.id.message); 130 if (tv == null) { 131 throw new RuntimeException("This OnScreenHint was not " 132 + "created with OnScreenHint.makeText()"); 133 } 134 tv.setText(s); 135 } 136 handleShow()137 private synchronized void handleShow() { 138 if (mView != mNextView) { 139 // remove the old view if necessary 140 handleHide(); 141 mView = mNextView; 142 if (mView.getParent() != null) { 143 mWM.removeView(mView); 144 } 145 146 mWM.addView(mView, mParams); 147 } 148 } 149 handleHide()150 private synchronized void handleHide() { 151 if (mView != null) { 152 // note: checking parent() just to make sure the view has 153 // been added... i have seen cases where we get here when 154 // the view isn't yet added, so let's try not to crash. 155 if (mView.getParent() != null) { 156 mWM.removeView(mView); 157 } 158 mView = null; 159 } 160 } 161 162 private final Runnable mShow = new Runnable() { 163 @Override 164 public void run() { 165 handleShow(); 166 } 167 }; 168 169 private final Runnable mHide = new Runnable() { 170 @Override 171 public void run() { 172 handleHide(); 173 } 174 }; 175 } 176