summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorSpike Sprague <spikuru@google.com>2014-02-27 14:33:21 -0800
committerSpike Sprague <spikuru@google.com>2014-03-04 14:09:28 -0800
commit82fa6ae85f7c07fef480eb1cd0cf7f578b150676 (patch)
treef0ec7afe0ad03c731c83609f2536bf7a78f83e79 /src
parent19259ea42f1ff0537847c9b5b3c01b4d0433a7d4 (diff)
downloadandroid_packages_apps_Camera2-82fa6ae85f7c07fef480eb1cd0cf7f578b150676.tar.gz
android_packages_apps_Camera2-82fa6ae85f7c07fef480eb1cd0cf7f578b150676.tar.bz2
android_packages_apps_Camera2-82fa6ae85f7c07fef480eb1cd0cf7f578b150676.zip
implement capture options animation
bug: 13100962 Change-Id: I1baf64693d0e01e99bfa19d0bd8699fd33d5812a
Diffstat (limited to 'src')
-rw-r--r--src/com/android/camera/widget/ModeOptions.java295
-rw-r--r--src/com/android/camera/widget/ModeOptionsOverlay.java21
2 files changed, 305 insertions, 11 deletions
diff --git a/src/com/android/camera/widget/ModeOptions.java b/src/com/android/camera/widget/ModeOptions.java
new file mode 100644
index 000000000..3233d196d
--- /dev/null
+++ b/src/com/android/camera/widget/ModeOptions.java
@@ -0,0 +1,295 @@
+/*
+ * 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.widget;
+
+import android.animation.Animator;
+import android.animation.AnimatorListenerAdapter;
+import android.animation.AnimatorSet;
+import android.animation.ObjectAnimator;
+import android.animation.ValueAnimator;
+import android.content.Context;
+import android.content.res.Configuration;
+import android.graphics.Canvas;
+import android.graphics.Path;
+import android.graphics.Paint;
+import android.graphics.RectF;
+import android.view.Gravity;
+import android.view.View;
+import android.widget.FrameLayout;
+import android.widget.LinearLayout;
+import android.util.AttributeSet;
+
+import com.android.camera.util.Gusterpolator;
+import com.android.camera2.R;
+
+public class ModeOptions extends FrameLayout {
+ private int mBackgroundColor;
+ private final Paint mPaint = new Paint();
+ private final Path mPath = new Path();
+ private boolean mIsHidden;
+ private RectF mAnimateFrom = new RectF();
+ private View mViewToShowHide;
+ private View mModeOptionsButtons;
+
+ private AnimatorSet mVisibleAnimator;
+ private AnimatorSet mHiddenAnimator;
+ private boolean mDrawCircle;
+ private boolean mFill;
+ private static final int RADIUS_ANIMATION_TIME = 250;
+ private static final int SHOW_ALPHA_ANIMATION_TIME = 350;
+ private static final int HIDE_ALPHA_ANIMATION_TIME = 200;
+ private static final int PADDING_ANIMATION_TIME = 90;
+
+ private int mParentSize;
+ private boolean mIsPortrait;
+
+ public ModeOptions(Context context, AttributeSet attrs) {
+ super(context, attrs);
+ }
+
+ public void setViewToShowHide(View v) {
+ mViewToShowHide = v;
+ }
+
+ @Override
+ public void onFinishInflate() {
+ mBackgroundColor = getResources().getColor(R.color.mode_options_background);
+ mPaint.setAntiAlias(true);
+ mPaint.setColor(mBackgroundColor);
+ mModeOptionsButtons = findViewById(R.id.mode_options_buttons);
+ }
+
+ @Override
+ public void onConfigurationChanged(Configuration config) {
+ super.onConfigurationChanged(config);
+
+ FrameLayout.LayoutParams params =
+ (FrameLayout.LayoutParams) mModeOptionsButtons.getLayoutParams();
+
+ if (config.orientation == Configuration.ORIENTATION_PORTRAIT) {
+ params.gravity = Gravity.RIGHT;
+ } else {
+ params.gravity = Gravity.TOP;
+ }
+
+ mVisibleAnimator.end();
+ mHiddenAnimator.end();
+
+ mModeOptionsButtons.setLayoutParams(params);
+ }
+
+
+ @Override
+ public void onLayout(boolean changed, int left, int top, int right, int bottom) {
+ if (changed) {
+ mIsPortrait = (getResources().getConfiguration().orientation ==
+ Configuration.ORIENTATION_PORTRAIT);
+
+ int buttonSize = getResources()
+ .getDimensionPixelSize(R.dimen.option_button_circle_size);
+ int buttonPadding = getResources()
+ .getDimensionPixelSize(R.dimen.mode_options_toggle_padding);
+
+ float rLeft, rRight, rTop, rBottom;
+ View parent = (View) getParent();
+ if (mIsPortrait) {
+ rLeft = getWidth() - buttonPadding - buttonSize;
+ rTop = (getHeight() - buttonSize) / 2.0f;
+
+ mParentSize = parent.getWidth();
+ } else {
+ rLeft = buttonPadding;
+ rTop = buttonPadding;
+
+ mParentSize = parent.getHeight();
+ }
+ rRight = rLeft + buttonSize;
+ rBottom = rTop + buttonSize;
+ mAnimateFrom.set(rLeft, rTop, rRight, rBottom);
+
+ setupAnimators();
+ }
+
+ super.onLayout(changed, left, top, right, bottom);
+ }
+
+ public boolean isHidden() {
+ return mIsHidden;
+ }
+
+ @Override
+ public void onDraw(Canvas canvas) {
+ if (mDrawCircle) {
+ canvas.drawPath(mPath, mPaint);
+ } else if (mFill) {
+ canvas.drawPaint(mPaint);
+ }
+ super.onDraw(canvas);
+ }
+
+ private void setupAnimators() {
+ final float fullSize = (mIsPortrait ? (float) getWidth() : (float) getHeight());
+
+ // show
+ {
+ final ValueAnimator radiusAnimator =
+ ValueAnimator.ofFloat(mAnimateFrom.width()/2.0f,
+ fullSize-mAnimateFrom.width()/2.0f);
+ radiusAnimator.setDuration(RADIUS_ANIMATION_TIME);
+ radiusAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
+ @Override
+ public void onAnimationUpdate(ValueAnimator animation) {
+ mPath.reset();
+ mPath.addCircle(mAnimateFrom.centerX(),
+ mAnimateFrom.centerY(),
+ (Float) animation.getAnimatedValue(),
+ Path.Direction.CW);
+ mDrawCircle = true;
+ mFill = false;
+ invalidate();
+ }
+ });
+ radiusAnimator.addListener(new AnimatorListenerAdapter() {
+ @Override
+ public void onAnimationEnd(Animator animation) {
+ mPath.reset();
+ mDrawCircle = false;
+ mFill = true;
+ invalidate();
+ }
+ });
+
+ final ValueAnimator alphaAnimator = ValueAnimator.ofFloat(1.0f, 1.0f);
+ alphaAnimator.setDuration(SHOW_ALPHA_ANIMATION_TIME);
+ alphaAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
+ @Override
+ public void onAnimationUpdate(ValueAnimator animation) {
+ mModeOptionsButtons.setAlpha((Float) animation.getAnimatedValue());
+ invalidate();
+ }
+ });
+ alphaAnimator.addListener(new AnimatorListenerAdapter() {
+ @Override
+ public void onAnimationEnd(Animator animation) {
+ mModeOptionsButtons.setAlpha(1.0f);
+ invalidate();
+ }
+ });
+
+ final ValueAnimator paddingAnimator = ValueAnimator.ofInt(mParentSize, 0);
+ paddingAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
+ @Override
+ public void onAnimationUpdate(ValueAnimator animation) {
+ if (mIsPortrait) {
+ mModeOptionsButtons
+ .setPadding((Integer) animation.getAnimatedValue(), 0, 0, 0);
+ } else {
+ mModeOptionsButtons
+ .setPadding(0, 0, 0, (Integer) animation.getAnimatedValue());
+ }
+ requestLayout();
+ invalidate();
+ }
+ });
+ paddingAnimator.setDuration(PADDING_ANIMATION_TIME);
+ paddingAnimator.addListener(new AnimatorListenerAdapter() {
+ @Override
+ public void onAnimationEnd(Animator animation) {
+ mModeOptionsButtons
+ .setPadding(0, 0, 0, 0);
+
+ requestLayout();
+ invalidate();
+ }
+ });
+
+ mVisibleAnimator = new AnimatorSet();
+ mVisibleAnimator.setInterpolator(Gusterpolator.INSTANCE);
+ mVisibleAnimator.playTogether(radiusAnimator, alphaAnimator, paddingAnimator);
+ }
+
+ // hide
+ {
+ final ValueAnimator radiusAnimator =
+ ValueAnimator.ofFloat(fullSize-mAnimateFrom.width()/2.0f,
+ mAnimateFrom.width()/2.0f);
+ radiusAnimator.setDuration(RADIUS_ANIMATION_TIME);
+ radiusAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
+ @Override
+ public void onAnimationUpdate(ValueAnimator animation) {
+ mPath.reset();
+ mPath.addCircle(mAnimateFrom.centerX(),
+ mAnimateFrom.centerY(),
+ (Float) animation.getAnimatedValue(),
+ Path.Direction.CW);
+ mDrawCircle = true;
+ mFill = false;
+ invalidate();
+ }
+ });
+ radiusAnimator.addListener(new AnimatorListenerAdapter() {
+ @Override
+ public void onAnimationEnd(Animator animation) {
+ if (mViewToShowHide != null) {
+ mPath.reset();
+ mViewToShowHide.setVisibility(View.VISIBLE);
+ mDrawCircle = false;
+ mFill = false;
+ invalidate();
+ }
+ }
+ });
+
+ final ValueAnimator alphaAnimator = ValueAnimator.ofFloat(1.0f, 0.0f);
+ alphaAnimator.setDuration(HIDE_ALPHA_ANIMATION_TIME);
+ alphaAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
+ @Override
+ public void onAnimationUpdate(ValueAnimator animation) {
+ mModeOptionsButtons.setAlpha((Float) animation.getAnimatedValue());
+ invalidate();
+ }
+ });
+ alphaAnimator.addListener(new AnimatorListenerAdapter() {
+ @Override
+ public void onAnimationEnd(Animator animation) {
+ mModeOptionsButtons.setAlpha(0.0f);
+ invalidate();
+ }
+ });
+
+ mHiddenAnimator = new AnimatorSet();
+ mHiddenAnimator.setInterpolator(Gusterpolator.INSTANCE);
+ mHiddenAnimator.playTogether(radiusAnimator, alphaAnimator);
+ }
+ }
+
+ public void animateVisible() {
+ mIsHidden = false;
+ if (mViewToShowHide != null) {
+ mViewToShowHide.setVisibility(View.INVISIBLE);
+ }
+ mHiddenAnimator.cancel();
+ mVisibleAnimator.end();
+ mVisibleAnimator.start();
+ }
+
+ public void animateHidden() {
+ mIsHidden = true;
+ mVisibleAnimator.cancel();
+ mHiddenAnimator.end();
+ mHiddenAnimator.start();
+ }
+} \ No newline at end of file
diff --git a/src/com/android/camera/widget/ModeOptionsOverlay.java b/src/com/android/camera/widget/ModeOptionsOverlay.java
index b7bb681d3..bd988dab2 100644
--- a/src/com/android/camera/widget/ModeOptionsOverlay.java
+++ b/src/com/android/camera/widget/ModeOptionsOverlay.java
@@ -56,7 +56,7 @@ public class ModeOptionsOverlay extends FrameLayout
private int mPreviewWidth;
private int mPreviewHeight;
- private TopRightWeightedLayout mModeOptions;
+ private ModeOptions mModeOptions;
// The mode options toggle can be either a default image, or a
// group of on screen indicators.
@@ -72,7 +72,7 @@ public class ModeOptionsOverlay extends FrameLayout
@Override
public void onFinishInflate() {
- mModeOptions = (TopRightWeightedLayout) findViewById(R.id.mode_options);
+ mModeOptions = (ModeOptions) findViewById(R.id.mode_options);
mModeOptions.setClickable(true);
mModeOptions.setOnClickListener(new View.OnClickListener() {
@Override
@@ -83,12 +83,12 @@ public class ModeOptionsOverlay extends FrameLayout
mModeOptionsToggle = (FrameLayout) findViewById(R.id.mode_options_toggle);
mModeOptionsToggle.setOnClickListener(new View.OnClickListener() {
- @Override
- public void onClick(View v) {
- mModeOptionsToggle.setVisibility(View.INVISIBLE);
- mModeOptions.setVisibility(View.VISIBLE);
- }
- });
+ @Override
+ public void onClick(View v) {
+ mModeOptions.animateVisible();
+ }
+ });
+ mModeOptions.setViewToShowHide(mModeOptionsToggle);
mThreeDots = (ImageView) findViewById(R.id.three_dots);
mIndicators = (LinearLayout) findViewById(R.id.indicator_icons);
@@ -121,11 +121,10 @@ public class ModeOptionsOverlay extends FrameLayout
*/
private void closeModeOptions() {
// Check that the bottom bar options are visible.
- if (mModeOptions.getVisibility() != View.VISIBLE) {
+ if (mModeOptions.isHidden()) {
return;
}
- mModeOptions.setVisibility(View.INVISIBLE);
- mModeOptionsToggle.setVisibility(View.VISIBLE);
+ mModeOptions.animateHidden();
}
@Override