182fa6ae85f7c07fef480eb1cd0cf7f578b150676Spike Sprague/* 282fa6ae85f7c07fef480eb1cd0cf7f578b150676Spike Sprague * Copyright (C) 2014 The Android Open Source Project 382fa6ae85f7c07fef480eb1cd0cf7f578b150676Spike Sprague * 482fa6ae85f7c07fef480eb1cd0cf7f578b150676Spike Sprague * Licensed under the Apache License, Version 2.0 (the "License"); 582fa6ae85f7c07fef480eb1cd0cf7f578b150676Spike Sprague * you may not use this file except in compliance with the License. 682fa6ae85f7c07fef480eb1cd0cf7f578b150676Spike Sprague * You may obtain a copy of the License at 782fa6ae85f7c07fef480eb1cd0cf7f578b150676Spike Sprague * 882fa6ae85f7c07fef480eb1cd0cf7f578b150676Spike Sprague * http://www.apache.org/licenses/LICENSE-2.0 982fa6ae85f7c07fef480eb1cd0cf7f578b150676Spike Sprague * 1082fa6ae85f7c07fef480eb1cd0cf7f578b150676Spike Sprague * Unless required by applicable law or agreed to in writing, software 1182fa6ae85f7c07fef480eb1cd0cf7f578b150676Spike Sprague * distributed under the License is distributed on an "AS IS" BASIS, 1282fa6ae85f7c07fef480eb1cd0cf7f578b150676Spike Sprague * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1382fa6ae85f7c07fef480eb1cd0cf7f578b150676Spike Sprague * See the License for the specific language governing permissions and 1482fa6ae85f7c07fef480eb1cd0cf7f578b150676Spike Sprague * limitations under the License. 1582fa6ae85f7c07fef480eb1cd0cf7f578b150676Spike Sprague */ 1682fa6ae85f7c07fef480eb1cd0cf7f578b150676Spike Spraguepackage com.android.camera.widget; 1782fa6ae85f7c07fef480eb1cd0cf7f578b150676Spike Sprague 1882fa6ae85f7c07fef480eb1cd0cf7f578b150676Spike Spragueimport android.animation.Animator; 1982fa6ae85f7c07fef480eb1cd0cf7f578b150676Spike Spragueimport android.animation.AnimatorListenerAdapter; 2082fa6ae85f7c07fef480eb1cd0cf7f578b150676Spike Spragueimport android.animation.AnimatorSet; 2182fa6ae85f7c07fef480eb1cd0cf7f578b150676Spike Spragueimport android.animation.ValueAnimator; 2282fa6ae85f7c07fef480eb1cd0cf7f578b150676Spike Spragueimport android.content.Context; 2382fa6ae85f7c07fef480eb1cd0cf7f578b150676Spike Spragueimport android.content.res.Configuration; 2482fa6ae85f7c07fef480eb1cd0cf7f578b150676Spike Spragueimport android.graphics.Canvas; 2582fa6ae85f7c07fef480eb1cd0cf7f578b150676Spike Spragueimport android.graphics.Paint; 2682fa6ae85f7c07fef480eb1cd0cf7f578b150676Spike Spragueimport android.graphics.RectF; 2718b22b5963e8871e539edf669d96862eec72bb5dSpike Spragueimport android.util.AttributeSet; 2882fa6ae85f7c07fef480eb1cd0cf7f578b150676Spike Spragueimport android.view.View; 2956d43cf80d40379d57ac1db697bc014d5c321b91Spike Spragueimport android.view.ViewGroup; 3082fa6ae85f7c07fef480eb1cd0cf7f578b150676Spike Spragueimport android.widget.FrameLayout; 31abf54e2994961395a0feb0b08353e62718443f23Spike Spragueimport android.widget.ImageButton; 3282fa6ae85f7c07fef480eb1cd0cf7f578b150676Spike Sprague 3318b22b5963e8871e539edf669d96862eec72bb5dSpike Spragueimport com.android.camera.MultiToggleImageButton; 3459345144c4bde59b81bb19c95cdd977c1d1a9cd4Spike Spragueimport com.android.camera.ui.RadioOptions; 3556d43cf80d40379d57ac1db697bc014d5c321b91Spike Spragueimport com.android.camera.ui.TopRightWeightedLayout; 3682fa6ae85f7c07fef480eb1cd0cf7f578b150676Spike Spragueimport com.android.camera.util.Gusterpolator; 3782fa6ae85f7c07fef480eb1cd0cf7f578b150676Spike Spragueimport com.android.camera2.R; 3882fa6ae85f7c07fef480eb1cd0cf7f578b150676Spike Sprague 3956d43cf80d40379d57ac1db697bc014d5c321b91Spike Spragueimport java.util.ArrayList; 4056d43cf80d40379d57ac1db697bc014d5c321b91Spike Sprague 4182fa6ae85f7c07fef480eb1cd0cf7f578b150676Spike Spraguepublic class ModeOptions extends FrameLayout { 4282fa6ae85f7c07fef480eb1cd0cf7f578b150676Spike Sprague private int mBackgroundColor; 4382fa6ae85f7c07fef480eb1cd0cf7f578b150676Spike Sprague private final Paint mPaint = new Paint(); 44591eec6465d29bbc053e164071c4c3a7c260a1d3Spike Sprague private boolean mIsHiddenOrHiding; 4582fa6ae85f7c07fef480eb1cd0cf7f578b150676Spike Sprague private RectF mAnimateFrom = new RectF(); 4682fa6ae85f7c07fef480eb1cd0cf7f578b150676Spike Sprague private View mViewToShowHide; 4756d43cf80d40379d57ac1db697bc014d5c321b91Spike Sprague private TopRightWeightedLayout mModeOptionsButtons; 4859345144c4bde59b81bb19c95cdd977c1d1a9cd4Spike Sprague private RadioOptions mModeOptionsPano; 4959345144c4bde59b81bb19c95cdd977c1d1a9cd4Spike Sprague private RadioOptions mModeOptionsExposure; 5082fa6ae85f7c07fef480eb1cd0cf7f578b150676Spike Sprague 5182fa6ae85f7c07fef480eb1cd0cf7f578b150676Spike Sprague private AnimatorSet mVisibleAnimator; 5282fa6ae85f7c07fef480eb1cd0cf7f578b150676Spike Sprague private AnimatorSet mHiddenAnimator; 5382fa6ae85f7c07fef480eb1cd0cf7f578b150676Spike Sprague private boolean mDrawCircle; 5482fa6ae85f7c07fef480eb1cd0cf7f578b150676Spike Sprague private boolean mFill; 5582fa6ae85f7c07fef480eb1cd0cf7f578b150676Spike Sprague private static final int RADIUS_ANIMATION_TIME = 250; 5682fa6ae85f7c07fef480eb1cd0cf7f578b150676Spike Sprague private static final int SHOW_ALPHA_ANIMATION_TIME = 350; 5782fa6ae85f7c07fef480eb1cd0cf7f578b150676Spike Sprague private static final int HIDE_ALPHA_ANIMATION_TIME = 200; 5856d43cf80d40379d57ac1db697bc014d5c321b91Spike Sprague private static final int PADDING_ANIMATION_TIME = 350; 5982fa6ae85f7c07fef480eb1cd0cf7f578b150676Spike Sprague 6059345144c4bde59b81bb19c95cdd977c1d1a9cd4Spike Sprague private ViewGroup mMainBar; 6159345144c4bde59b81bb19c95cdd977c1d1a9cd4Spike Sprague private ViewGroup mActiveBar; 6259345144c4bde59b81bb19c95cdd977c1d1a9cd4Spike Sprague public static final int BAR_INVALID = -1; 6359345144c4bde59b81bb19c95cdd977c1d1a9cd4Spike Sprague public static final int BAR_STANDARD = 0; 6459345144c4bde59b81bb19c95cdd977c1d1a9cd4Spike Sprague public static final int BAR_PANO = 1; 6559345144c4bde59b81bb19c95cdd977c1d1a9cd4Spike Sprague 6682fa6ae85f7c07fef480eb1cd0cf7f578b150676Spike Sprague private boolean mIsPortrait; 674df915872c25fe61640a94c7a2c5f27eee1a1048Doris Liu private float mRadius = 0f; 6882fa6ae85f7c07fef480eb1cd0cf7f578b150676Spike Sprague 6982fa6ae85f7c07fef480eb1cd0cf7f578b150676Spike Sprague public ModeOptions(Context context, AttributeSet attrs) { 7082fa6ae85f7c07fef480eb1cd0cf7f578b150676Spike Sprague super(context, attrs); 7182fa6ae85f7c07fef480eb1cd0cf7f578b150676Spike Sprague } 7282fa6ae85f7c07fef480eb1cd0cf7f578b150676Spike Sprague 7382fa6ae85f7c07fef480eb1cd0cf7f578b150676Spike Sprague public void setViewToShowHide(View v) { 7482fa6ae85f7c07fef480eb1cd0cf7f578b150676Spike Sprague mViewToShowHide = v; 7582fa6ae85f7c07fef480eb1cd0cf7f578b150676Spike Sprague } 7682fa6ae85f7c07fef480eb1cd0cf7f578b150676Spike Sprague 7782fa6ae85f7c07fef480eb1cd0cf7f578b150676Spike Sprague @Override 7882fa6ae85f7c07fef480eb1cd0cf7f578b150676Spike Sprague public void onFinishInflate() { 79591eec6465d29bbc053e164071c4c3a7c260a1d3Spike Sprague mIsHiddenOrHiding = true; 8082fa6ae85f7c07fef480eb1cd0cf7f578b150676Spike Sprague mBackgroundColor = getResources().getColor(R.color.mode_options_background); 8182fa6ae85f7c07fef480eb1cd0cf7f578b150676Spike Sprague mPaint.setAntiAlias(true); 8282fa6ae85f7c07fef480eb1cd0cf7f578b150676Spike Sprague mPaint.setColor(mBackgroundColor); 8356d43cf80d40379d57ac1db697bc014d5c321b91Spike Sprague mModeOptionsButtons = (TopRightWeightedLayout) findViewById(R.id.mode_options_buttons); 8459345144c4bde59b81bb19c95cdd977c1d1a9cd4Spike Sprague mModeOptionsPano = (RadioOptions) findViewById(R.id.mode_options_pano); 8559345144c4bde59b81bb19c95cdd977c1d1a9cd4Spike Sprague mModeOptionsExposure = (RadioOptions) findViewById(R.id.mode_options_exposure); 8659345144c4bde59b81bb19c95cdd977c1d1a9cd4Spike Sprague mMainBar = mActiveBar = mModeOptionsButtons; 87abf54e2994961395a0feb0b08353e62718443f23Spike Sprague 88abf54e2994961395a0feb0b08353e62718443f23Spike Sprague ImageButton exposureButton = (ImageButton) findViewById(R.id.exposure_button); 89abf54e2994961395a0feb0b08353e62718443f23Spike Sprague exposureButton.setOnClickListener(new View.OnClickListener() { 90abf54e2994961395a0feb0b08353e62718443f23Spike Sprague @Override 91abf54e2994961395a0feb0b08353e62718443f23Spike Sprague public void onClick(View v) { 9259345144c4bde59b81bb19c95cdd977c1d1a9cd4Spike Sprague mActiveBar = mModeOptionsExposure; 9359345144c4bde59b81bb19c95cdd977c1d1a9cd4Spike Sprague mMainBar.setVisibility(View.INVISIBLE); 9459345144c4bde59b81bb19c95cdd977c1d1a9cd4Spike Sprague mActiveBar.setVisibility(View.VISIBLE); 95abf54e2994961395a0feb0b08353e62718443f23Spike Sprague } 96abf54e2994961395a0feb0b08353e62718443f23Spike Sprague }); 9782fa6ae85f7c07fef480eb1cd0cf7f578b150676Spike Sprague } 9882fa6ae85f7c07fef480eb1cd0cf7f578b150676Spike Sprague 9959345144c4bde59b81bb19c95cdd977c1d1a9cd4Spike Sprague public void setMainBar(int b) { 10059345144c4bde59b81bb19c95cdd977c1d1a9cd4Spike Sprague for (int i = 0; i < getChildCount(); i++) { 10159345144c4bde59b81bb19c95cdd977c1d1a9cd4Spike Sprague getChildAt(i).setVisibility(View.INVISIBLE); 10282fa6ae85f7c07fef480eb1cd0cf7f578b150676Spike Sprague } 10359345144c4bde59b81bb19c95cdd977c1d1a9cd4Spike Sprague switch (b) { 10459345144c4bde59b81bb19c95cdd977c1d1a9cd4Spike Sprague case BAR_STANDARD: 10559345144c4bde59b81bb19c95cdd977c1d1a9cd4Spike Sprague mMainBar = mActiveBar = mModeOptionsButtons; 10659345144c4bde59b81bb19c95cdd977c1d1a9cd4Spike Sprague break; 10759345144c4bde59b81bb19c95cdd977c1d1a9cd4Spike Sprague case BAR_PANO: 10859345144c4bde59b81bb19c95cdd977c1d1a9cd4Spike Sprague mMainBar = mActiveBar = mModeOptionsPano; 10959345144c4bde59b81bb19c95cdd977c1d1a9cd4Spike Sprague break; 11059345144c4bde59b81bb19c95cdd977c1d1a9cd4Spike Sprague } 11159345144c4bde59b81bb19c95cdd977c1d1a9cd4Spike Sprague mMainBar.setVisibility(View.VISIBLE); 11259345144c4bde59b81bb19c95cdd977c1d1a9cd4Spike Sprague } 11382fa6ae85f7c07fef480eb1cd0cf7f578b150676Spike Sprague 11459345144c4bde59b81bb19c95cdd977c1d1a9cd4Spike Sprague public int getMainBar() { 11559345144c4bde59b81bb19c95cdd977c1d1a9cd4Spike Sprague if (mMainBar == mModeOptionsButtons) { 11659345144c4bde59b81bb19c95cdd977c1d1a9cd4Spike Sprague return BAR_STANDARD; 11759345144c4bde59b81bb19c95cdd977c1d1a9cd4Spike Sprague } 11859345144c4bde59b81bb19c95cdd977c1d1a9cd4Spike Sprague if (mMainBar == mModeOptionsPano) { 11959345144c4bde59b81bb19c95cdd977c1d1a9cd4Spike Sprague return BAR_PANO; 12059345144c4bde59b81bb19c95cdd977c1d1a9cd4Spike Sprague } 12159345144c4bde59b81bb19c95cdd977c1d1a9cd4Spike Sprague return BAR_INVALID; 12282fa6ae85f7c07fef480eb1cd0cf7f578b150676Spike Sprague } 12382fa6ae85f7c07fef480eb1cd0cf7f578b150676Spike Sprague 124abf54e2994961395a0feb0b08353e62718443f23Spike Sprague @Override 125abf54e2994961395a0feb0b08353e62718443f23Spike Sprague public void onWindowVisibilityChanged(int visibility) { 126abf54e2994961395a0feb0b08353e62718443f23Spike Sprague super.onWindowVisibilityChanged(visibility); 127abf54e2994961395a0feb0b08353e62718443f23Spike Sprague if (visibility != VISIBLE && !mIsHiddenOrHiding) { 128abf54e2994961395a0feb0b08353e62718443f23Spike Sprague // Collapse mode options when window is not visible. 129abf54e2994961395a0feb0b08353e62718443f23Spike Sprague setVisibility(INVISIBLE); 13059345144c4bde59b81bb19c95cdd977c1d1a9cd4Spike Sprague if (mMainBar != null) { 13159345144c4bde59b81bb19c95cdd977c1d1a9cd4Spike Sprague mMainBar.setVisibility(VISIBLE); 13259345144c4bde59b81bb19c95cdd977c1d1a9cd4Spike Sprague } 13359345144c4bde59b81bb19c95cdd977c1d1a9cd4Spike Sprague if (mActiveBar != null && mActiveBar != mMainBar) { 13459345144c4bde59b81bb19c95cdd977c1d1a9cd4Spike Sprague mActiveBar.setVisibility(INVISIBLE); 135abf54e2994961395a0feb0b08353e62718443f23Spike Sprague } 136abf54e2994961395a0feb0b08353e62718443f23Spike Sprague if (mViewToShowHide != null) { 137abf54e2994961395a0feb0b08353e62718443f23Spike Sprague mViewToShowHide.setVisibility(VISIBLE); 138abf54e2994961395a0feb0b08353e62718443f23Spike Sprague } 139abf54e2994961395a0feb0b08353e62718443f23Spike Sprague mIsHiddenOrHiding = true; 140abf54e2994961395a0feb0b08353e62718443f23Spike Sprague } 141abf54e2994961395a0feb0b08353e62718443f23Spike Sprague } 142abf54e2994961395a0feb0b08353e62718443f23Spike Sprague 14382fa6ae85f7c07fef480eb1cd0cf7f578b150676Spike Sprague @Override 14482fa6ae85f7c07fef480eb1cd0cf7f578b150676Spike Sprague public void onLayout(boolean changed, int left, int top, int right, int bottom) { 14582fa6ae85f7c07fef480eb1cd0cf7f578b150676Spike Sprague if (changed) { 14682fa6ae85f7c07fef480eb1cd0cf7f578b150676Spike Sprague mIsPortrait = (getResources().getConfiguration().orientation == 14782fa6ae85f7c07fef480eb1cd0cf7f578b150676Spike Sprague Configuration.ORIENTATION_PORTRAIT); 14882fa6ae85f7c07fef480eb1cd0cf7f578b150676Spike Sprague 14982fa6ae85f7c07fef480eb1cd0cf7f578b150676Spike Sprague int buttonSize = getResources() 15082fa6ae85f7c07fef480eb1cd0cf7f578b150676Spike Sprague .getDimensionPixelSize(R.dimen.option_button_circle_size); 15182fa6ae85f7c07fef480eb1cd0cf7f578b150676Spike Sprague int buttonPadding = getResources() 15282fa6ae85f7c07fef480eb1cd0cf7f578b150676Spike Sprague .getDimensionPixelSize(R.dimen.mode_options_toggle_padding); 15382fa6ae85f7c07fef480eb1cd0cf7f578b150676Spike Sprague 15482fa6ae85f7c07fef480eb1cd0cf7f578b150676Spike Sprague float rLeft, rRight, rTop, rBottom; 15582fa6ae85f7c07fef480eb1cd0cf7f578b150676Spike Sprague if (mIsPortrait) { 15682fa6ae85f7c07fef480eb1cd0cf7f578b150676Spike Sprague rLeft = getWidth() - buttonPadding - buttonSize; 15782fa6ae85f7c07fef480eb1cd0cf7f578b150676Spike Sprague rTop = (getHeight() - buttonSize) / 2.0f; 15882fa6ae85f7c07fef480eb1cd0cf7f578b150676Spike Sprague } else { 15982fa6ae85f7c07fef480eb1cd0cf7f578b150676Spike Sprague rLeft = buttonPadding; 16082fa6ae85f7c07fef480eb1cd0cf7f578b150676Spike Sprague rTop = buttonPadding; 16182fa6ae85f7c07fef480eb1cd0cf7f578b150676Spike Sprague } 16282fa6ae85f7c07fef480eb1cd0cf7f578b150676Spike Sprague rRight = rLeft + buttonSize; 16382fa6ae85f7c07fef480eb1cd0cf7f578b150676Spike Sprague rBottom = rTop + buttonSize; 16482fa6ae85f7c07fef480eb1cd0cf7f578b150676Spike Sprague mAnimateFrom.set(rLeft, rTop, rRight, rBottom); 16582fa6ae85f7c07fef480eb1cd0cf7f578b150676Spike Sprague 16682fa6ae85f7c07fef480eb1cd0cf7f578b150676Spike Sprague setupAnimators(); 16718b22b5963e8871e539edf669d96862eec72bb5dSpike Sprague setupToggleButtonParams(); 16882fa6ae85f7c07fef480eb1cd0cf7f578b150676Spike Sprague } 16982fa6ae85f7c07fef480eb1cd0cf7f578b150676Spike Sprague 17082fa6ae85f7c07fef480eb1cd0cf7f578b150676Spike Sprague super.onLayout(changed, left, top, right, bottom); 17182fa6ae85f7c07fef480eb1cd0cf7f578b150676Spike Sprague } 17282fa6ae85f7c07fef480eb1cd0cf7f578b150676Spike Sprague 17382fa6ae85f7c07fef480eb1cd0cf7f578b150676Spike Sprague @Override 17482fa6ae85f7c07fef480eb1cd0cf7f578b150676Spike Sprague public void onDraw(Canvas canvas) { 17582fa6ae85f7c07fef480eb1cd0cf7f578b150676Spike Sprague if (mDrawCircle) { 1764df915872c25fe61640a94c7a2c5f27eee1a1048Doris Liu canvas.drawCircle(mAnimateFrom.centerX(), mAnimateFrom.centerY(), mRadius, mPaint); 17782fa6ae85f7c07fef480eb1cd0cf7f578b150676Spike Sprague } else if (mFill) { 17882fa6ae85f7c07fef480eb1cd0cf7f578b150676Spike Sprague canvas.drawPaint(mPaint); 17982fa6ae85f7c07fef480eb1cd0cf7f578b150676Spike Sprague } 18082fa6ae85f7c07fef480eb1cd0cf7f578b150676Spike Sprague super.onDraw(canvas); 18182fa6ae85f7c07fef480eb1cd0cf7f578b150676Spike Sprague } 18282fa6ae85f7c07fef480eb1cd0cf7f578b150676Spike Sprague 18318b22b5963e8871e539edf669d96862eec72bb5dSpike Sprague private void setupToggleButtonParams() { 18418b22b5963e8871e539edf669d96862eec72bb5dSpike Sprague int size = (mIsPortrait ? getHeight() : getWidth()); 18518b22b5963e8871e539edf669d96862eec72bb5dSpike Sprague 18618b22b5963e8871e539edf669d96862eec72bb5dSpike Sprague for (int i = 0; i < mModeOptionsButtons.getChildCount(); i++) { 18718b22b5963e8871e539edf669d96862eec72bb5dSpike Sprague View button = mModeOptionsButtons.getChildAt(i); 18818b22b5963e8871e539edf669d96862eec72bb5dSpike Sprague if (button instanceof MultiToggleImageButton) { 18918b22b5963e8871e539edf669d96862eec72bb5dSpike Sprague MultiToggleImageButton toggleButton = (MultiToggleImageButton) button; 19018b22b5963e8871e539edf669d96862eec72bb5dSpike Sprague toggleButton.setParentSize(size); 19118b22b5963e8871e539edf669d96862eec72bb5dSpike Sprague toggleButton.setAnimDirection(mIsPortrait ? 19218b22b5963e8871e539edf669d96862eec72bb5dSpike Sprague MultiToggleImageButton.ANIM_DIRECTION_VERTICAL : 19318b22b5963e8871e539edf669d96862eec72bb5dSpike Sprague MultiToggleImageButton.ANIM_DIRECTION_HORIZONTAL); 19418b22b5963e8871e539edf669d96862eec72bb5dSpike Sprague } 19518b22b5963e8871e539edf669d96862eec72bb5dSpike Sprague } 19618b22b5963e8871e539edf669d96862eec72bb5dSpike Sprague } 19718b22b5963e8871e539edf669d96862eec72bb5dSpike Sprague 19882fa6ae85f7c07fef480eb1cd0cf7f578b150676Spike Sprague private void setupAnimators() { 199fd29a841a046c6a02306adc9e4df1a5eeb466f39Spike Sprague if (mVisibleAnimator != null) { 200fd29a841a046c6a02306adc9e4df1a5eeb466f39Spike Sprague mVisibleAnimator.end(); 201fd29a841a046c6a02306adc9e4df1a5eeb466f39Spike Sprague } 202fd29a841a046c6a02306adc9e4df1a5eeb466f39Spike Sprague if (mHiddenAnimator != null) { 203fd29a841a046c6a02306adc9e4df1a5eeb466f39Spike Sprague mHiddenAnimator.end(); 204fd29a841a046c6a02306adc9e4df1a5eeb466f39Spike Sprague } 205fd29a841a046c6a02306adc9e4df1a5eeb466f39Spike Sprague 20682fa6ae85f7c07fef480eb1cd0cf7f578b150676Spike Sprague final float fullSize = (mIsPortrait ? (float) getWidth() : (float) getHeight()); 20782fa6ae85f7c07fef480eb1cd0cf7f578b150676Spike Sprague 20882fa6ae85f7c07fef480eb1cd0cf7f578b150676Spike Sprague // show 20982fa6ae85f7c07fef480eb1cd0cf7f578b150676Spike Sprague { 21082fa6ae85f7c07fef480eb1cd0cf7f578b150676Spike Sprague final ValueAnimator radiusAnimator = 21182fa6ae85f7c07fef480eb1cd0cf7f578b150676Spike Sprague ValueAnimator.ofFloat(mAnimateFrom.width()/2.0f, 21282fa6ae85f7c07fef480eb1cd0cf7f578b150676Spike Sprague fullSize-mAnimateFrom.width()/2.0f); 21382fa6ae85f7c07fef480eb1cd0cf7f578b150676Spike Sprague radiusAnimator.setDuration(RADIUS_ANIMATION_TIME); 21482fa6ae85f7c07fef480eb1cd0cf7f578b150676Spike Sprague radiusAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { 21582fa6ae85f7c07fef480eb1cd0cf7f578b150676Spike Sprague @Override 21682fa6ae85f7c07fef480eb1cd0cf7f578b150676Spike Sprague public void onAnimationUpdate(ValueAnimator animation) { 2174df915872c25fe61640a94c7a2c5f27eee1a1048Doris Liu mRadius = (Float) animation.getAnimatedValue(); 21882fa6ae85f7c07fef480eb1cd0cf7f578b150676Spike Sprague mDrawCircle = true; 21982fa6ae85f7c07fef480eb1cd0cf7f578b150676Spike Sprague mFill = false; 22082fa6ae85f7c07fef480eb1cd0cf7f578b150676Spike Sprague } 22182fa6ae85f7c07fef480eb1cd0cf7f578b150676Spike Sprague }); 22282fa6ae85f7c07fef480eb1cd0cf7f578b150676Spike Sprague radiusAnimator.addListener(new AnimatorListenerAdapter() { 22382fa6ae85f7c07fef480eb1cd0cf7f578b150676Spike Sprague @Override 22482fa6ae85f7c07fef480eb1cd0cf7f578b150676Spike Sprague public void onAnimationEnd(Animator animation) { 22582fa6ae85f7c07fef480eb1cd0cf7f578b150676Spike Sprague mDrawCircle = false; 22682fa6ae85f7c07fef480eb1cd0cf7f578b150676Spike Sprague mFill = true; 22782fa6ae85f7c07fef480eb1cd0cf7f578b150676Spike Sprague } 22882fa6ae85f7c07fef480eb1cd0cf7f578b150676Spike Sprague }); 22982fa6ae85f7c07fef480eb1cd0cf7f578b150676Spike Sprague 23056d43cf80d40379d57ac1db697bc014d5c321b91Spike Sprague final ValueAnimator alphaAnimator = ValueAnimator.ofFloat(0.0f, 1.0f); 23182fa6ae85f7c07fef480eb1cd0cf7f578b150676Spike Sprague alphaAnimator.setDuration(SHOW_ALPHA_ANIMATION_TIME); 23282fa6ae85f7c07fef480eb1cd0cf7f578b150676Spike Sprague alphaAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { 23382fa6ae85f7c07fef480eb1cd0cf7f578b150676Spike Sprague @Override 23482fa6ae85f7c07fef480eb1cd0cf7f578b150676Spike Sprague public void onAnimationUpdate(ValueAnimator animation) { 23559345144c4bde59b81bb19c95cdd977c1d1a9cd4Spike Sprague mActiveBar.setAlpha((Float) animation.getAnimatedValue()); 23682fa6ae85f7c07fef480eb1cd0cf7f578b150676Spike Sprague } 23782fa6ae85f7c07fef480eb1cd0cf7f578b150676Spike Sprague }); 23882fa6ae85f7c07fef480eb1cd0cf7f578b150676Spike Sprague alphaAnimator.addListener(new AnimatorListenerAdapter() { 23982fa6ae85f7c07fef480eb1cd0cf7f578b150676Spike Sprague @Override 24082fa6ae85f7c07fef480eb1cd0cf7f578b150676Spike Sprague public void onAnimationEnd(Animator animation) { 24159345144c4bde59b81bb19c95cdd977c1d1a9cd4Spike Sprague mActiveBar.setAlpha(1.0f); 24282fa6ae85f7c07fef480eb1cd0cf7f578b150676Spike Sprague } 24382fa6ae85f7c07fef480eb1cd0cf7f578b150676Spike Sprague }); 24482fa6ae85f7c07fef480eb1cd0cf7f578b150676Spike Sprague 24556d43cf80d40379d57ac1db697bc014d5c321b91Spike Sprague final int deltaX = getResources() 24656d43cf80d40379d57ac1db697bc014d5c321b91Spike Sprague .getDimensionPixelSize(R.dimen.mode_options_buttons_anim_delta_x); 24759345144c4bde59b81bb19c95cdd977c1d1a9cd4Spike Sprague int childCount = mActiveBar.getChildCount(); 24856d43cf80d40379d57ac1db697bc014d5c321b91Spike Sprague ArrayList<Animator> paddingAnimators = new ArrayList<Animator>(); 24956d43cf80d40379d57ac1db697bc014d5c321b91Spike Sprague for (int i = 0; i < childCount; i++) { 25056d43cf80d40379d57ac1db697bc014d5c321b91Spike Sprague final View button; 25156d43cf80d40379d57ac1db697bc014d5c321b91Spike Sprague if (mIsPortrait) { 25259345144c4bde59b81bb19c95cdd977c1d1a9cd4Spike Sprague button = mActiveBar.getChildAt(i); 25356d43cf80d40379d57ac1db697bc014d5c321b91Spike Sprague } else { 25459345144c4bde59b81bb19c95cdd977c1d1a9cd4Spike Sprague button = mActiveBar.getChildAt(childCount-1-i); 25582fa6ae85f7c07fef480eb1cd0cf7f578b150676Spike Sprague } 25682fa6ae85f7c07fef480eb1cd0cf7f578b150676Spike Sprague 25759345144c4bde59b81bb19c95cdd977c1d1a9cd4Spike Sprague final ValueAnimator paddingAnimator = 25818b22b5963e8871e539edf669d96862eec72bb5dSpike Sprague ValueAnimator.ofFloat(deltaX*(childCount-i), 0.0f); 25959345144c4bde59b81bb19c95cdd977c1d1a9cd4Spike Sprague paddingAnimator.setDuration(PADDING_ANIMATION_TIME); 26059345144c4bde59b81bb19c95cdd977c1d1a9cd4Spike Sprague paddingAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { 26159345144c4bde59b81bb19c95cdd977c1d1a9cd4Spike Sprague @Override 26259345144c4bde59b81bb19c95cdd977c1d1a9cd4Spike Sprague public void onAnimationUpdate(ValueAnimator animation) { 26359345144c4bde59b81bb19c95cdd977c1d1a9cd4Spike Sprague if (mIsPortrait) { 26459345144c4bde59b81bb19c95cdd977c1d1a9cd4Spike Sprague button.setTranslationX((Float) animation.getAnimatedValue()); 26559345144c4bde59b81bb19c95cdd977c1d1a9cd4Spike Sprague } else { 26659345144c4bde59b81bb19c95cdd977c1d1a9cd4Spike Sprague button.setTranslationY(-((Float) animation.getAnimatedValue())); 26756d43cf80d40379d57ac1db697bc014d5c321b91Spike Sprague } 26859345144c4bde59b81bb19c95cdd977c1d1a9cd4Spike Sprague invalidate(); 26959345144c4bde59b81bb19c95cdd977c1d1a9cd4Spike Sprague } 27059345144c4bde59b81bb19c95cdd977c1d1a9cd4Spike Sprague }); 27156d43cf80d40379d57ac1db697bc014d5c321b91Spike Sprague 27259345144c4bde59b81bb19c95cdd977c1d1a9cd4Spike Sprague paddingAnimators.add(paddingAnimator); 27356d43cf80d40379d57ac1db697bc014d5c321b91Spike Sprague } 27459345144c4bde59b81bb19c95cdd977c1d1a9cd4Spike Sprague 27556d43cf80d40379d57ac1db697bc014d5c321b91Spike Sprague AnimatorSet paddingAnimatorSet = new AnimatorSet(); 27656d43cf80d40379d57ac1db697bc014d5c321b91Spike Sprague paddingAnimatorSet.playTogether(paddingAnimators); 27782fa6ae85f7c07fef480eb1cd0cf7f578b150676Spike Sprague 27882fa6ae85f7c07fef480eb1cd0cf7f578b150676Spike Sprague mVisibleAnimator = new AnimatorSet(); 27982fa6ae85f7c07fef480eb1cd0cf7f578b150676Spike Sprague mVisibleAnimator.setInterpolator(Gusterpolator.INSTANCE); 28056d43cf80d40379d57ac1db697bc014d5c321b91Spike Sprague mVisibleAnimator.playTogether(radiusAnimator, alphaAnimator, paddingAnimatorSet); 28182fa6ae85f7c07fef480eb1cd0cf7f578b150676Spike Sprague } 28282fa6ae85f7c07fef480eb1cd0cf7f578b150676Spike Sprague 28382fa6ae85f7c07fef480eb1cd0cf7f578b150676Spike Sprague // hide 28482fa6ae85f7c07fef480eb1cd0cf7f578b150676Spike Sprague { 28582fa6ae85f7c07fef480eb1cd0cf7f578b150676Spike Sprague final ValueAnimator radiusAnimator = 28682fa6ae85f7c07fef480eb1cd0cf7f578b150676Spike Sprague ValueAnimator.ofFloat(fullSize-mAnimateFrom.width()/2.0f, 28782fa6ae85f7c07fef480eb1cd0cf7f578b150676Spike Sprague mAnimateFrom.width()/2.0f); 28882fa6ae85f7c07fef480eb1cd0cf7f578b150676Spike Sprague radiusAnimator.setDuration(RADIUS_ANIMATION_TIME); 28982fa6ae85f7c07fef480eb1cd0cf7f578b150676Spike Sprague radiusAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { 29082fa6ae85f7c07fef480eb1cd0cf7f578b150676Spike Sprague @Override 29182fa6ae85f7c07fef480eb1cd0cf7f578b150676Spike Sprague public void onAnimationUpdate(ValueAnimator animation) { 2924df915872c25fe61640a94c7a2c5f27eee1a1048Doris Liu mRadius = (Float) animation.getAnimatedValue(); 29382fa6ae85f7c07fef480eb1cd0cf7f578b150676Spike Sprague mDrawCircle = true; 29482fa6ae85f7c07fef480eb1cd0cf7f578b150676Spike Sprague mFill = false; 29582fa6ae85f7c07fef480eb1cd0cf7f578b150676Spike Sprague invalidate(); 29682fa6ae85f7c07fef480eb1cd0cf7f578b150676Spike Sprague } 29782fa6ae85f7c07fef480eb1cd0cf7f578b150676Spike Sprague }); 29882fa6ae85f7c07fef480eb1cd0cf7f578b150676Spike Sprague radiusAnimator.addListener(new AnimatorListenerAdapter() { 29982fa6ae85f7c07fef480eb1cd0cf7f578b150676Spike Sprague @Override 30082fa6ae85f7c07fef480eb1cd0cf7f578b150676Spike Sprague public void onAnimationEnd(Animator animation) { 30182fa6ae85f7c07fef480eb1cd0cf7f578b150676Spike Sprague if (mViewToShowHide != null) { 30282fa6ae85f7c07fef480eb1cd0cf7f578b150676Spike Sprague mViewToShowHide.setVisibility(View.VISIBLE); 30382fa6ae85f7c07fef480eb1cd0cf7f578b150676Spike Sprague mDrawCircle = false; 30482fa6ae85f7c07fef480eb1cd0cf7f578b150676Spike Sprague mFill = false; 30582fa6ae85f7c07fef480eb1cd0cf7f578b150676Spike Sprague invalidate(); 30682fa6ae85f7c07fef480eb1cd0cf7f578b150676Spike Sprague } 30782fa6ae85f7c07fef480eb1cd0cf7f578b150676Spike Sprague } 30882fa6ae85f7c07fef480eb1cd0cf7f578b150676Spike Sprague }); 30982fa6ae85f7c07fef480eb1cd0cf7f578b150676Spike Sprague 31082fa6ae85f7c07fef480eb1cd0cf7f578b150676Spike Sprague final ValueAnimator alphaAnimator = ValueAnimator.ofFloat(1.0f, 0.0f); 31182fa6ae85f7c07fef480eb1cd0cf7f578b150676Spike Sprague alphaAnimator.setDuration(HIDE_ALPHA_ANIMATION_TIME); 31282fa6ae85f7c07fef480eb1cd0cf7f578b150676Spike Sprague alphaAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { 31382fa6ae85f7c07fef480eb1cd0cf7f578b150676Spike Sprague @Override 31482fa6ae85f7c07fef480eb1cd0cf7f578b150676Spike Sprague public void onAnimationUpdate(ValueAnimator animation) { 31559345144c4bde59b81bb19c95cdd977c1d1a9cd4Spike Sprague mActiveBar.setAlpha((Float) animation.getAnimatedValue()); 31682fa6ae85f7c07fef480eb1cd0cf7f578b150676Spike Sprague invalidate(); 31782fa6ae85f7c07fef480eb1cd0cf7f578b150676Spike Sprague } 31882fa6ae85f7c07fef480eb1cd0cf7f578b150676Spike Sprague }); 31982fa6ae85f7c07fef480eb1cd0cf7f578b150676Spike Sprague alphaAnimator.addListener(new AnimatorListenerAdapter() { 32082fa6ae85f7c07fef480eb1cd0cf7f578b150676Spike Sprague @Override 32182fa6ae85f7c07fef480eb1cd0cf7f578b150676Spike Sprague public void onAnimationEnd(Animator animation) { 3222a58938576e6d4220c02cf0b9a8226a1d3bcf176Spike Sprague setVisibility(View.INVISIBLE); 32359345144c4bde59b81bb19c95cdd977c1d1a9cd4Spike Sprague if (mActiveBar != mMainBar) { 32459345144c4bde59b81bb19c95cdd977c1d1a9cd4Spike Sprague mActiveBar.setAlpha(1.0f); 32559345144c4bde59b81bb19c95cdd977c1d1a9cd4Spike Sprague mActiveBar.setVisibility(View.INVISIBLE); 32659345144c4bde59b81bb19c95cdd977c1d1a9cd4Spike Sprague } 32759345144c4bde59b81bb19c95cdd977c1d1a9cd4Spike Sprague mMainBar.setAlpha(1.0f); 32859345144c4bde59b81bb19c95cdd977c1d1a9cd4Spike Sprague mMainBar.setVisibility(View.VISIBLE); 32959345144c4bde59b81bb19c95cdd977c1d1a9cd4Spike Sprague mActiveBar = mMainBar; 33082fa6ae85f7c07fef480eb1cd0cf7f578b150676Spike Sprague invalidate(); 33182fa6ae85f7c07fef480eb1cd0cf7f578b150676Spike Sprague } 33282fa6ae85f7c07fef480eb1cd0cf7f578b150676Spike Sprague }); 33382fa6ae85f7c07fef480eb1cd0cf7f578b150676Spike Sprague 33482fa6ae85f7c07fef480eb1cd0cf7f578b150676Spike Sprague mHiddenAnimator = new AnimatorSet(); 33582fa6ae85f7c07fef480eb1cd0cf7f578b150676Spike Sprague mHiddenAnimator.setInterpolator(Gusterpolator.INSTANCE); 33682fa6ae85f7c07fef480eb1cd0cf7f578b150676Spike Sprague mHiddenAnimator.playTogether(radiusAnimator, alphaAnimator); 33782fa6ae85f7c07fef480eb1cd0cf7f578b150676Spike Sprague } 33882fa6ae85f7c07fef480eb1cd0cf7f578b150676Spike Sprague } 33982fa6ae85f7c07fef480eb1cd0cf7f578b150676Spike Sprague 34082fa6ae85f7c07fef480eb1cd0cf7f578b150676Spike Sprague public void animateVisible() { 341591eec6465d29bbc053e164071c4c3a7c260a1d3Spike Sprague if (mIsHiddenOrHiding) { 342591eec6465d29bbc053e164071c4c3a7c260a1d3Spike Sprague if (mViewToShowHide != null) { 343591eec6465d29bbc053e164071c4c3a7c260a1d3Spike Sprague mViewToShowHide.setVisibility(View.INVISIBLE); 344591eec6465d29bbc053e164071c4c3a7c260a1d3Spike Sprague } 345591eec6465d29bbc053e164071c4c3a7c260a1d3Spike Sprague mHiddenAnimator.cancel(); 346591eec6465d29bbc053e164071c4c3a7c260a1d3Spike Sprague mVisibleAnimator.end(); 3472a58938576e6d4220c02cf0b9a8226a1d3bcf176Spike Sprague setVisibility(View.VISIBLE); 348591eec6465d29bbc053e164071c4c3a7c260a1d3Spike Sprague mVisibleAnimator.start(); 34982fa6ae85f7c07fef480eb1cd0cf7f578b150676Spike Sprague } 350591eec6465d29bbc053e164071c4c3a7c260a1d3Spike Sprague mIsHiddenOrHiding = false; 35182fa6ae85f7c07fef480eb1cd0cf7f578b150676Spike Sprague } 35282fa6ae85f7c07fef480eb1cd0cf7f578b150676Spike Sprague 35382fa6ae85f7c07fef480eb1cd0cf7f578b150676Spike Sprague public void animateHidden() { 354591eec6465d29bbc053e164071c4c3a7c260a1d3Spike Sprague if (!mIsHiddenOrHiding) { 355591eec6465d29bbc053e164071c4c3a7c260a1d3Spike Sprague mVisibleAnimator.cancel(); 356591eec6465d29bbc053e164071c4c3a7c260a1d3Spike Sprague mHiddenAnimator.end(); 357591eec6465d29bbc053e164071c4c3a7c260a1d3Spike Sprague mHiddenAnimator.start(); 358591eec6465d29bbc053e164071c4c3a7c260a1d3Spike Sprague } 359591eec6465d29bbc053e164071c4c3a7c260a1d3Spike Sprague mIsHiddenOrHiding = true; 36082fa6ae85f7c07fef480eb1cd0cf7f578b150676Spike Sprague } 36182fa6ae85f7c07fef480eb1cd0cf7f578b150676Spike Sprague}