| /* |
| * Copyright (C) 2014 The Android Open Source Project |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| |
| package com.android.camera.ui; |
| |
| import java.util.Locale; |
| |
| import android.content.Context; |
| import android.graphics.RectF; |
| import android.os.Handler; |
| import android.os.Message; |
| import android.util.AttributeSet; |
| import android.view.View; |
| import android.widget.FrameLayout; |
| import android.widget.TextView; |
| |
| import com.android.camera.debug.Log; |
| import com.android.camera2.R; |
| |
| /** |
| * This class manages the looks of the countdown. |
| */ |
| public class CountDownView extends FrameLayout { |
| |
| private static final Log.Tag TAG = new Log.Tag("CountDownView"); |
| private static final int SET_TIMER_TEXT = 1; |
| private static final long ANIMATION_DURATION_MS = 800; |
| private TextView mRemainingSecondsView; |
| private int mRemainingSecs = 0; |
| private OnCountDownStatusListener mListener; |
| private final Handler mHandler = new MainHandler(); |
| private final RectF mPreviewArea = new RectF(); |
| |
| /** |
| * Listener that gets notified when the countdown status has |
| * been updated (i.e. remaining seconds changed, or finished). |
| */ |
| public interface OnCountDownStatusListener { |
| /** |
| * Gets notified when the remaining seconds for the countdown |
| * has changed. |
| * |
| * @param remainingSeconds seconds remained for countdown |
| */ |
| public void onRemainingSecondsChanged(int remainingSeconds); |
| |
| /** |
| * Gets called when countdown is finished. |
| */ |
| public void onCountDownFinished(); |
| } |
| |
| public CountDownView(Context context, AttributeSet attrs) { |
| super(context, attrs); |
| } |
| |
| /** |
| * Returns whether countdown is on-going. |
| */ |
| public boolean isCountingDown() { |
| return mRemainingSecs > 0; |
| }; |
| |
| /** |
| * Responds to preview area change by centering th countdown UI in the new |
| * preview area. |
| */ |
| public void onPreviewAreaChanged(RectF previewArea) { |
| mPreviewArea.set(previewArea); |
| } |
| |
| private void remainingSecondsChanged(int newVal) { |
| mRemainingSecs = newVal; |
| if (mListener != null) { |
| mListener.onRemainingSecondsChanged(mRemainingSecs); |
| } |
| |
| if (newVal == 0) { |
| // Countdown has finished. |
| setVisibility(View.INVISIBLE); |
| if (mListener != null) { |
| mListener.onCountDownFinished(); |
| } |
| } else { |
| Locale locale = getResources().getConfiguration().locale; |
| String localizedValue = String.format(locale, "%d", newVal); |
| mRemainingSecondsView.setText(localizedValue); |
| // Fade-out animation. |
| startFadeOutAnimation(); |
| // Schedule the next remainingSecondsChanged() call in 1 second |
| mHandler.sendEmptyMessageDelayed(SET_TIMER_TEXT, 1000); |
| } |
| } |
| |
| private void startFadeOutAnimation() { |
| int textWidth = mRemainingSecondsView.getMeasuredWidth(); |
| int textHeight = mRemainingSecondsView.getMeasuredHeight(); |
| mRemainingSecondsView.setScaleX(1f); |
| mRemainingSecondsView.setScaleY(1f); |
| mRemainingSecondsView.setTranslationX(mPreviewArea.centerX() - textWidth / 2); |
| mRemainingSecondsView.setTranslationY(mPreviewArea.centerY() - textHeight / 2); |
| mRemainingSecondsView.setPivotX(textWidth / 2); |
| mRemainingSecondsView.setPivotY(textHeight / 2); |
| mRemainingSecondsView.setAlpha(1f); |
| float endScale = 2.5f; |
| mRemainingSecondsView.animate().scaleX(endScale).scaleY(endScale) |
| .alpha(0f).setDuration(ANIMATION_DURATION_MS).start(); |
| } |
| |
| @Override |
| protected void onFinishInflate() { |
| super.onFinishInflate(); |
| mRemainingSecondsView = (TextView) findViewById(R.id.remaining_seconds); |
| } |
| |
| /** |
| * Sets a listener that gets notified when the status of countdown has changed. |
| */ |
| public void setCountDownStatusListener(OnCountDownStatusListener listener) { |
| mListener = listener; |
| } |
| |
| /** |
| * Starts showing countdown in the UI. |
| * |
| * @param sec duration of the countdown, in seconds |
| */ |
| public void startCountDown(int sec) { |
| if (sec <= 0) { |
| Log.w(TAG, "Invalid input for countdown timer: " + sec + " seconds"); |
| return; |
| } |
| if (isCountingDown()) { |
| cancelCountDown(); |
| } |
| setVisibility(View.VISIBLE); |
| remainingSecondsChanged(sec); |
| } |
| |
| /** |
| * Cancels the on-going countdown in the UI, if any. |
| */ |
| public void cancelCountDown() { |
| if (mRemainingSecs > 0) { |
| mRemainingSecs = 0; |
| mHandler.removeMessages(SET_TIMER_TEXT); |
| setVisibility(View.INVISIBLE); |
| } |
| } |
| |
| private class MainHandler extends Handler { |
| @Override |
| public void handleMessage(Message message) { |
| if (message.what == SET_TIMER_TEXT) { |
| remainingSecondsChanged(mRemainingSecs -1); |
| } |
| } |
| } |
| } |