CameraSwitcher.java revision d9a36946b24f4ccd697aa0139aa978c962eb95e1
1/* 2 * Copyright (C) 2012 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.ui; 18 19import android.animation.Animator; 20import android.animation.Animator.AnimatorListener; 21import android.animation.AnimatorListenerAdapter; 22import android.content.Context; 23import android.util.AttributeSet; 24import android.view.LayoutInflater; 25import android.view.MotionEvent; 26import android.view.View; 27import android.view.View.OnClickListener; 28import android.view.View.OnTouchListener; 29import android.view.ViewGroup; 30import android.widget.LinearLayout; 31 32import com.android.camera.R; 33import com.android.gallery3d.common.ApiHelper; 34 35public class CameraSwitcher extends RotateImageView 36 implements OnClickListener, OnTouchListener { 37 38 private static final String TAG = "CAM_Switcher"; 39 40 public interface CameraSwitchListener { 41 42 public void onCameraSelected(int i); 43 } 44 45 private CameraSwitchListener mListener; 46 private int mCurrentIndex; 47 private int[] mDrawIds; 48 private int mItemSize; 49 private View mPopup; 50 private View mParent; 51 private boolean mShowingPopup; 52 private boolean mNeedsAnimationSetup; 53 54 private AnimatorListener mHideAnimationListener; 55 private AnimatorListener mShowAnimationListener; 56 57 public CameraSwitcher(Context context) { 58 super(context); 59 init(context); 60 } 61 62 public CameraSwitcher(Context context, AttributeSet attrs) { 63 super(context, attrs); 64 init(context); 65 } 66 67 private void init(Context context) { 68 mItemSize = context.getResources().getDimensionPixelSize(R.dimen.switcher_size); 69 setOnClickListener(this); 70 } 71 72 public void setDrawIds(int[] drawids) { 73 mDrawIds = drawids; 74 } 75 76 public void setCurrentIndex(int i) { 77 mCurrentIndex = i; 78 setImageResource(mDrawIds[i]); 79 } 80 81 public void setSwitchListener(CameraSwitchListener l) { 82 mListener = l; 83 } 84 85 @Override 86 public void onClick(View v) { 87 showSwitcher(); 88 } 89 90 private void onCameraSelected(int ix) { 91 hidePopup(); 92 if ((ix != mCurrentIndex) && (mListener != null)) { 93 setCurrentIndex(ix); 94 mListener.onCameraSelected(ix); 95 } 96 } 97 98 private void initPopup() { 99 mParent = LayoutInflater.from(getContext()).inflate(R.layout.switcher_popup, 100 (ViewGroup) getParent()); 101 LinearLayout content = (LinearLayout) mParent.findViewById(R.id.content); 102 mPopup = content; 103 mPopup.setVisibility(View.INVISIBLE); 104 mNeedsAnimationSetup = true; 105 for (int i = mDrawIds.length - 1; i >= 0; i--) { 106 RotateImageView item = new RotateImageView(getContext()); 107 item.setImageResource(mDrawIds[i]); 108 item.setBackgroundResource(R.drawable.bg_pressed); 109 final int index = i; 110 item.setOnClickListener(new OnClickListener() { 111 @Override 112 public void onClick(View v) { 113 onCameraSelected(index); 114 } 115 }); 116 switch (mDrawIds[i]) { 117 case R.drawable.ic_switch_camera: 118 item.setContentDescription(getContext().getResources().getString( 119 R.string.accessibility_switch_to_camera)); 120 break; 121 case R.drawable.ic_switch_video: 122 item.setContentDescription(getContext().getResources().getString( 123 R.string.accessibility_switch_to_video)); 124 break; 125 case R.drawable.ic_switch_pan: 126 item.setContentDescription(getContext().getResources().getString( 127 R.string.accessibility_switch_to_panorama)); 128 break; 129 case com.android.gallery3d.R.drawable.ic_menu_photosphere: 130 item.setContentDescription(getContext().getResources().getString( 131 R.string.accessibility_switch_to_lightcycle)); 132 break; 133 default: 134 break; 135 } 136 content.addView(item, new LinearLayout.LayoutParams(mItemSize, mItemSize)); 137 } 138 } 139 140 public boolean showsPopup() { 141 return mShowingPopup; 142 } 143 144 public boolean isInsidePopup(MotionEvent evt) { 145 if (!showsPopup()) return false; 146 return evt.getX() >= mPopup.getLeft() 147 && evt.getX() < mPopup.getRight() 148 && evt.getY() >= mPopup.getTop() 149 && evt.getY() < mPopup.getBottom(); 150 } 151 152 private void hidePopup() { 153 mShowingPopup = false; 154 setVisibility(View.VISIBLE); 155 if (mPopup != null && !animateHidePopup()) { 156 mPopup.setVisibility(View.INVISIBLE); 157 } 158 mParent.setOnTouchListener(null); 159 } 160 161 private void showSwitcher() { 162 mShowingPopup = true; 163 if (mPopup == null) { 164 initPopup(); 165 } 166 mPopup.setVisibility(View.VISIBLE); 167 if (!animateShowPopup()) { 168 setVisibility(View.INVISIBLE); 169 } 170 mParent.setOnTouchListener(this); 171 } 172 173 @Override 174 public boolean onTouch(View v, MotionEvent event) { 175 if (showsPopup()) { 176 hidePopup(); 177 } 178 return true; 179 } 180 181 @Override 182 public void setOrientation(int degree, boolean animate) { 183 super.setOrientation(degree, animate); 184 ViewGroup content = (ViewGroup) mPopup; 185 if (content == null) return; 186 for (int i = 0; i < content.getChildCount(); i++) { 187 RotateImageView iv = (RotateImageView) content.getChildAt(i); 188 iv.setOrientation(degree, animate); 189 } 190 } 191 192 private void popupAnimationSetup() { 193 if (!ApiHelper.HAS_VIEW_PROPERTY_ANIMATOR) { 194 return; 195 } 196 mPopup.setScaleX(0.3f); 197 mPopup.setScaleY(0.3f); 198 mPopup.setTranslationX(-getWidth() / 2); 199 mPopup.setTranslationY(getHeight()); 200 mNeedsAnimationSetup = false; 201 } 202 203 private boolean animateHidePopup() { 204 if (!ApiHelper.HAS_VIEW_PROPERTY_ANIMATOR) { 205 return false; 206 } 207 if (mHideAnimationListener == null) { 208 mHideAnimationListener = new AnimatorListenerAdapter() { 209 @Override 210 public void onAnimationEnd(Animator animation) { 211 // Verify that we weren't canceled 212 if (!showsPopup()) { 213 mPopup.setVisibility(View.INVISIBLE); 214 } 215 } 216 }; 217 } 218 mPopup.animate() 219 .alpha(0f) 220 .scaleX(0.3f).scaleY(0.3f) 221 .translationX(-getWidth() / 2) 222 .translationY(getHeight()) 223 .setListener(mHideAnimationListener); 224 animate().alpha(1f).setListener(null); 225 return true; 226 } 227 228 private boolean animateShowPopup() { 229 if (!ApiHelper.HAS_VIEW_PROPERTY_ANIMATOR) { 230 return false; 231 } 232 if (mNeedsAnimationSetup) { 233 popupAnimationSetup(); 234 } 235 if (mShowAnimationListener == null) { 236 mShowAnimationListener = new AnimatorListenerAdapter() { 237 @Override 238 public void onAnimationEnd(Animator animation) { 239 // Verify that we weren't canceled 240 if (showsPopup()) { 241 setVisibility(View.INVISIBLE); 242 } 243 } 244 }; 245 } 246 mPopup.animate() 247 .alpha(1f) 248 .scaleX(1f).scaleY(1f) 249 .translationX(0) 250 .translationY(0) 251 .setListener(null); 252 animate().alpha(0f) 253 .setListener(mShowAnimationListener); 254 return true; 255 } 256} 257