ShutterButton.java revision b64d345c9d51cabce43b5191532a0c185d2a70a5
1/* 2 * Copyright (C) 2008 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.util.AttributeSet; 21import android.widget.ImageView; 22 23/** 24 * A button designed to be used for the on-screen shutter button. 25 * It's currently an ImageView that can call a delegate when the pressed state changes. 26 */ 27public class ShutterButton extends ImageView { 28 /** 29 * Interface definition for a callback to be invoked when a ModeButton's pressed state changes. 30 */ 31 public interface OnShutterButtonListener { 32 /** 33 * Called when a ShutterButton has been pressed. 34 * 35 * @param b The ShutterButton that was pressed. 36 */ 37 void onShutterButtonFocus(ShutterButton b, boolean pressed); 38 void onShutterButtonClick(ShutterButton b); 39 } 40 41 private OnShutterButtonListener mListener; 42 private boolean mOldPressed; 43 44 public ShutterButton(Context context) { 45 super(context); 46 } 47 48 public ShutterButton(Context context, AttributeSet attrs) { 49 super(context, attrs); 50 } 51 52 public ShutterButton(Context context, AttributeSet attrs, int defStyle) { 53 super(context, attrs, defStyle); 54 } 55 56 public void setOnShutterButtonListener(OnShutterButtonListener listener) { 57 mListener = listener; 58 } 59 60 /** 61 * Hook into the drawable state changing to get changes to isPressed -- the 62 * onPressed listener doesn't always get called when the pressed state changes. 63 */ 64 @Override 65 protected void drawableStateChanged() { 66 super.drawableStateChanged(); 67 final boolean pressed = isPressed(); 68 if (pressed != mOldPressed) { 69 if (!pressed) { 70 // When pressing the physical camera button the sequence of events is: 71 // focus pressed, optional camera pressed, focus released. 72 // We want to emulate this sequence of events with the shutter button. 73 // When clicking using a trackball button, the view system changes 74 // the the drawable state before posting click notification, so the 75 // sequence of events is: 76 // pressed(true), optional click, pressed(false) 77 // When clicking using touch events, the view system changes the 78 // drawable state after posting click notification, so the sequence of 79 // events is: 80 // pressed(true), pressed(false), optional click 81 // Since we're emulating the physical camera button, we want to have the 82 // same order of events. So we want the optional click callback to be delivered 83 // before the pressed(false) callback. 84 // 85 // To do this, we delay the posting of the pressed(false) event slightly by 86 // pushing it on the event queue. This moves it after the optional click 87 // notification, so our client always sees events in this sequence: 88 // pressed(true), optional click, pressed(false) 89 post(new Runnable() { 90 public void run() { 91 callShutterButtonFocus(pressed); 92 } 93 }); 94 } else { 95 callShutterButtonFocus(pressed); 96 } 97 mOldPressed = pressed; 98 } 99 } 100 101 private void callShutterButtonFocus(boolean pressed) { 102 if (mListener != null) { 103 mListener.onShutterButtonFocus(this, pressed); 104 } 105 } 106 107 @Override 108 public boolean performClick() { 109 boolean result = super.performClick(); 110 if (mListener != null) { 111 mListener.onShutterButtonClick(this); 112 } 113 return result; 114 } 115} 116