BottomBar.java revision a1ec04a9f9526418f5cb17a5afbfc48aca1e02d0
10744e4ab3ec5f0270bdad33e7c477f52ba680bbdMarco Nelissen/* 20744e4ab3ec5f0270bdad33e7c477f52ba680bbdMarco Nelissen * Copyright (C) 2013 The Android Open Source Project 30744e4ab3ec5f0270bdad33e7c477f52ba680bbdMarco Nelissen * 40744e4ab3ec5f0270bdad33e7c477f52ba680bbdMarco Nelissen * Licensed under the Apache License, Version 2.0 (the "License"); 50744e4ab3ec5f0270bdad33e7c477f52ba680bbdMarco Nelissen * you may not use this file except in compliance with the License. 60744e4ab3ec5f0270bdad33e7c477f52ba680bbdMarco Nelissen * You may obtain a copy of the License at 70744e4ab3ec5f0270bdad33e7c477f52ba680bbdMarco Nelissen * 80744e4ab3ec5f0270bdad33e7c477f52ba680bbdMarco Nelissen * http://www.apache.org/licenses/LICENSE-2.0 90744e4ab3ec5f0270bdad33e7c477f52ba680bbdMarco Nelissen * 100744e4ab3ec5f0270bdad33e7c477f52ba680bbdMarco Nelissen * Unless required by applicable law or agreed to in writing, software 110744e4ab3ec5f0270bdad33e7c477f52ba680bbdMarco Nelissen * distributed under the License is distributed on an "AS IS" BASIS, 120744e4ab3ec5f0270bdad33e7c477f52ba680bbdMarco Nelissen * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 130744e4ab3ec5f0270bdad33e7c477f52ba680bbdMarco Nelissen * See the License for the specific language governing permissions and 140744e4ab3ec5f0270bdad33e7c477f52ba680bbdMarco Nelissen * limitations under the License. 150744e4ab3ec5f0270bdad33e7c477f52ba680bbdMarco Nelissen */ 160744e4ab3ec5f0270bdad33e7c477f52ba680bbdMarco Nelissen 170744e4ab3ec5f0270bdad33e7c477f52ba680bbdMarco Nelissenpackage com.android.camera.ui; 180744e4ab3ec5f0270bdad33e7c477f52ba680bbdMarco Nelissen 1939f8a7647aa4051a1c260b9496c2db82f93f8667Spike Spragueimport android.animation.Animator; 2039f8a7647aa4051a1c260b9496c2db82f93f8667Spike Spragueimport android.animation.AnimatorListenerAdapter; 2139f8a7647aa4051a1c260b9496c2db82f93f8667Spike Spragueimport android.animation.ValueAnimator; 220744e4ab3ec5f0270bdad33e7c477f52ba680bbdMarco Nelissenimport android.content.Context; 230744e4ab3ec5f0270bdad33e7c477f52ba680bbdMarco Nelissenimport android.content.res.Configuration; 24a1ec04a9f9526418f5cb17a5afbfc48aca1e02d0Doris Liuimport android.graphics.RectF; 250744e4ab3ec5f0270bdad33e7c477f52ba680bbdMarco Nelissenimport android.util.AttributeSet; 260744e4ab3ec5f0270bdad33e7c477f52ba680bbdMarco Nelissenimport android.view.Gravity; 274efa8b54c1df4e06f2d3caed2568015a737f9ddaErin Dahlgrenimport android.view.MotionEvent; 280744e4ab3ec5f0270bdad33e7c477f52ba680bbdMarco Nelissenimport android.view.View; 290744e4ab3ec5f0270bdad33e7c477f52ba680bbdMarco Nelissenimport android.widget.FrameLayout; 301648c36927501ff32bf2918e8a445118d5208731Erin Dahlgrenimport android.widget.LinearLayout; 310744e4ab3ec5f0270bdad33e7c477f52ba680bbdMarco Nelissen 3239f8a7647aa4051a1c260b9496c2db82f93f8667Spike Spragueimport com.android.camera.ShutterButton; 334efa8b54c1df4e06f2d3caed2568015a737f9ddaErin Dahlgrenimport com.android.camera.ToggleImageButton; 3439f8a7647aa4051a1c260b9496c2db82f93f8667Spike Spragueimport com.android.camera.util.Gusterpolator; 3539f8a7647aa4051a1c260b9496c2db82f93f8667Spike Spragueimport com.android.camera2.R; 3639f8a7647aa4051a1c260b9496c2db82f93f8667Spike Sprague 3739f8a7647aa4051a1c260b9496c2db82f93f8667Spike Spragueimport android.graphics.Canvas; 3839f8a7647aa4051a1c260b9496c2db82f93f8667Spike Spragueimport android.graphics.Path; 3939f8a7647aa4051a1c260b9496c2db82f93f8667Spike Spragueimport android.graphics.Paint; 4039f8a7647aa4051a1c260b9496c2db82f93f8667Spike Spragueimport android.graphics.drawable.Drawable; 4139f8a7647aa4051a1c260b9496c2db82f93f8667Spike Spragueimport android.graphics.drawable.TransitionDrawable; 4270da918464276b110c43868caa272c97baadb89eDoris Liu 430744e4ab3ec5f0270bdad33e7c477f52ba680bbdMarco Nelissen/** 440744e4ab3ec5f0270bdad33e7c477f52ba680bbdMarco Nelissen * BottomBar swaps its width and height on rotation. In addition, it also changes 450744e4ab3ec5f0270bdad33e7c477f52ba680bbdMarco Nelissen * gravity and layout orientation based on the new orientation. Specifically, in 460744e4ab3ec5f0270bdad33e7c477f52ba680bbdMarco Nelissen * landscape it aligns to the right side of its parent and lays out its children 470744e4ab3ec5f0270bdad33e7c477f52ba680bbdMarco Nelissen * vertically, whereas in portrait, it stays at the bottom of the parent and has 480744e4ab3ec5f0270bdad33e7c477f52ba680bbdMarco Nelissen * a horizontal layout orientation. 4939f8a7647aa4051a1c260b9496c2db82f93f8667Spike Sprague*/ 5070da918464276b110c43868caa272c97baadb89eDoris Liupublic class BottomBar extends FrameLayout 5156688f7019fbe4dee110b7600349f48da9fff601Erin Dahlgren implements PreviewStatusListener.PreviewAreaSizeChangedListener, 5256688f7019fbe4dee110b7600349f48da9fff601Erin Dahlgren PreviewOverlay.OnPreviewTouchedListener { 533b92e2f8e6d91af1b83c8bee95bd93e7153b96daSpike Sprague 5470da918464276b110c43868caa272c97baadb89eDoris Liu private static final String TAG = "BottomBar"; 5539f8a7647aa4051a1c260b9496c2db82f93f8667Spike Sprague 5656688f7019fbe4dee110b7600349f48da9fff601Erin Dahlgren private static final int BOTTOMBAR_OPTIONS_TIMEOUT_MS = 2000; 5756688f7019fbe4dee110b7600349f48da9fff601Erin Dahlgren 5839f8a7647aa4051a1c260b9496c2db82f93f8667Spike Sprague private static final float CIRCLE_RADIUS = 64.0f; 5939f8a7647aa4051a1c260b9496c2db82f93f8667Spike Sprague private static final int CIRCLE_ANIM_DURATION_MS = 450; 6039f8a7647aa4051a1c260b9496c2db82f93f8667Spike Sprague 6170da918464276b110c43868caa272c97baadb89eDoris Liu private int mWidth; 6270da918464276b110c43868caa272c97baadb89eDoris Liu private int mHeight; 6370da918464276b110c43868caa272c97baadb89eDoris Liu private float mOffsetShorterEdge; 6470da918464276b110c43868caa272c97baadb89eDoris Liu private float mOffsetLongerEdge; 6570da918464276b110c43868caa272c97baadb89eDoris Liu 6670da918464276b110c43868caa272c97baadb89eDoris Liu private final int mOptimalHeight; 6770da918464276b110c43868caa272c97baadb89eDoris Liu private boolean mOverLayBottomBar; 680744e4ab3ec5f0270bdad33e7c477f52ba680bbdMarco Nelissen 6956688f7019fbe4dee110b7600349f48da9fff601Erin Dahlgren private ToggleImageButton mOptionsToggle; 7056688f7019fbe4dee110b7600349f48da9fff601Erin Dahlgren 7156688f7019fbe4dee110b7600349f48da9fff601Erin Dahlgren private TopRightMostOverlay mOptionsOverlay; 7256688f7019fbe4dee110b7600349f48da9fff601Erin Dahlgren private TopRightWeightedLayout mOptionsLayout; 734efa8b54c1df4e06f2d3caed2568015a737f9ddaErin Dahlgren private FrameLayout mCaptureLayout; 744efa8b54c1df4e06f2d3caed2568015a737f9ddaErin Dahlgren private TopRightWeightedLayout mIntentLayout; 7556688f7019fbe4dee110b7600349f48da9fff601Erin Dahlgren private boolean mIsCaptureIntent = false; 7656688f7019fbe4dee110b7600349f48da9fff601Erin Dahlgren 7756688f7019fbe4dee110b7600349f48da9fff601Erin Dahlgren /** 7856688f7019fbe4dee110b7600349f48da9fff601Erin Dahlgren * A generic Runnable for setting the options toggle 7956688f7019fbe4dee110b7600349f48da9fff601Erin Dahlgren * to the capture layout state and performing the state 8056688f7019fbe4dee110b7600349f48da9fff601Erin Dahlgren * transition. 8156688f7019fbe4dee110b7600349f48da9fff601Erin Dahlgren */ 8256688f7019fbe4dee110b7600349f48da9fff601Erin Dahlgren private final Runnable mCloseOptionsRunnable = 8356688f7019fbe4dee110b7600349f48da9fff601Erin Dahlgren new Runnable() { 8456688f7019fbe4dee110b7600349f48da9fff601Erin Dahlgren @Override 8556688f7019fbe4dee110b7600349f48da9fff601Erin Dahlgren public void run() { 8656688f7019fbe4dee110b7600349f48da9fff601Erin Dahlgren if (mOptionsToggle != null) { 8756688f7019fbe4dee110b7600349f48da9fff601Erin Dahlgren mOptionsToggle.setState(0, true); 8856688f7019fbe4dee110b7600349f48da9fff601Erin Dahlgren } 8956688f7019fbe4dee110b7600349f48da9fff601Erin Dahlgren } 9056688f7019fbe4dee110b7600349f48da9fff601Erin Dahlgren }; 914efa8b54c1df4e06f2d3caed2568015a737f9ddaErin Dahlgren 9239f8a7647aa4051a1c260b9496c2db82f93f8667Spike Sprague private ShutterButton mShutterButton; 9339f8a7647aa4051a1c260b9496c2db82f93f8667Spike Sprague 9439f8a7647aa4051a1c260b9496c2db82f93f8667Spike Sprague private int mBackgroundColor; 95b92910e04c4da91fc4ea5a9484b83f9ecba1c896Spike Sprague private int mBackgroundPressedColor; 96b92910e04c4da91fc4ea5a9484b83f9ecba1c896Spike Sprague private int mBackgroundAlpha = 0xff; 97b92910e04c4da91fc4ea5a9484b83f9ecba1c896Spike Sprague 9839f8a7647aa4051a1c260b9496c2db82f93f8667Spike Sprague private Paint mCirclePaint = new Paint(); 9939f8a7647aa4051a1c260b9496c2db82f93f8667Spike Sprague private Path mCirclePath = new Path(); 10039f8a7647aa4051a1c260b9496c2db82f93f8667Spike Sprague 1010744e4ab3ec5f0270bdad33e7c477f52ba680bbdMarco Nelissen public BottomBar(Context context, AttributeSet attrs) { 1020744e4ab3ec5f0270bdad33e7c477f52ba680bbdMarco Nelissen super(context, attrs); 10370da918464276b110c43868caa272c97baadb89eDoris Liu mOptimalHeight = getResources().getDimensionPixelSize(R.dimen.bottom_bar_height_optimal); 1040744e4ab3ec5f0270bdad33e7c477f52ba680bbdMarco Nelissen } 1050744e4ab3ec5f0270bdad33e7c477f52ba680bbdMarco Nelissen 106b92910e04c4da91fc4ea5a9484b83f9ecba1c896Spike Sprague private void setPaintColor(int alpha, int color) { 107b92910e04c4da91fc4ea5a9484b83f9ecba1c896Spike Sprague mCirclePaint.setColor((alpha << 24) | (color & 0x00ffffff)); 108b92910e04c4da91fc4ea5a9484b83f9ecba1c896Spike Sprague } 109b92910e04c4da91fc4ea5a9484b83f9ecba1c896Spike Sprague 1104efa8b54c1df4e06f2d3caed2568015a737f9ddaErin Dahlgren @Override 1114efa8b54c1df4e06f2d3caed2568015a737f9ddaErin Dahlgren public void onFinishInflate() { 11256688f7019fbe4dee110b7600349f48da9fff601Erin Dahlgren mOptionsOverlay 11356688f7019fbe4dee110b7600349f48da9fff601Erin Dahlgren = (TopRightMostOverlay) findViewById(R.id.bottombar_options_overlay); 11456688f7019fbe4dee110b7600349f48da9fff601Erin Dahlgren mOptionsLayout 11556688f7019fbe4dee110b7600349f48da9fff601Erin Dahlgren = (TopRightWeightedLayout) findViewById(R.id.bottombar_options); 1164efa8b54c1df4e06f2d3caed2568015a737f9ddaErin Dahlgren mCaptureLayout 1174efa8b54c1df4e06f2d3caed2568015a737f9ddaErin Dahlgren = (FrameLayout) findViewById(R.id.bottombar_capture); 1184efa8b54c1df4e06f2d3caed2568015a737f9ddaErin Dahlgren mIntentLayout 1194efa8b54c1df4e06f2d3caed2568015a737f9ddaErin Dahlgren = (TopRightWeightedLayout) findViewById(R.id.bottombar_intent); 120b92910e04c4da91fc4ea5a9484b83f9ecba1c896Spike Sprague 12139f8a7647aa4051a1c260b9496c2db82f93f8667Spike Sprague mShutterButton 12239f8a7647aa4051a1c260b9496c2db82f93f8667Spike Sprague = (ShutterButton) findViewById(R.id.shutter_button); 123b92910e04c4da91fc4ea5a9484b83f9ecba1c896Spike Sprague mShutterButton.setOnTouchListener(new OnTouchListener() { 124b92910e04c4da91fc4ea5a9484b83f9ecba1c896Spike Sprague @Override 125b92910e04c4da91fc4ea5a9484b83f9ecba1c896Spike Sprague public boolean onTouch(View v, MotionEvent event) { 126b92910e04c4da91fc4ea5a9484b83f9ecba1c896Spike Sprague if (MotionEvent.ACTION_DOWN == event.getActionMasked()) { 127b92910e04c4da91fc4ea5a9484b83f9ecba1c896Spike Sprague setPaintColor(mBackgroundAlpha, mBackgroundPressedColor); 128b92910e04c4da91fc4ea5a9484b83f9ecba1c896Spike Sprague invalidate(); 129b92910e04c4da91fc4ea5a9484b83f9ecba1c896Spike Sprague } else if (MotionEvent.ACTION_UP == event.getActionMasked()) { 130b92910e04c4da91fc4ea5a9484b83f9ecba1c896Spike Sprague setPaintColor(mBackgroundAlpha, mBackgroundColor); 131b92910e04c4da91fc4ea5a9484b83f9ecba1c896Spike Sprague invalidate(); 132b92910e04c4da91fc4ea5a9484b83f9ecba1c896Spike Sprague } 133b92910e04c4da91fc4ea5a9484b83f9ecba1c896Spike Sprague 134b92910e04c4da91fc4ea5a9484b83f9ecba1c896Spike Sprague return false; 135b92910e04c4da91fc4ea5a9484b83f9ecba1c896Spike Sprague } 136b92910e04c4da91fc4ea5a9484b83f9ecba1c896Spike Sprague }); 13756688f7019fbe4dee110b7600349f48da9fff601Erin Dahlgren 13856688f7019fbe4dee110b7600349f48da9fff601Erin Dahlgren mOptionsOverlay.setOnTouchListener(new View.OnTouchListener() { 13939f8a7647aa4051a1c260b9496c2db82f93f8667Spike Sprague @Override 14039f8a7647aa4051a1c260b9496c2db82f93f8667Spike Sprague public boolean onTouch(View v, MotionEvent event) { 14139f8a7647aa4051a1c260b9496c2db82f93f8667Spike Sprague if (event.getActionMasked() == MotionEvent.ACTION_DOWN) { 14239f8a7647aa4051a1c260b9496c2db82f93f8667Spike Sprague // close options immediately. 14339f8a7647aa4051a1c260b9496c2db82f93f8667Spike Sprague closeModeOptionsDelayed(BOTTOMBAR_OPTIONS_TIMEOUT_MS); 14456688f7019fbe4dee110b7600349f48da9fff601Erin Dahlgren } 14539f8a7647aa4051a1c260b9496c2db82f93f8667Spike Sprague // Let touch event reach mode options or shutter. 14639f8a7647aa4051a1c260b9496c2db82f93f8667Spike Sprague return false; 14739f8a7647aa4051a1c260b9496c2db82f93f8667Spike Sprague } 14839f8a7647aa4051a1c260b9496c2db82f93f8667Spike Sprague }); 14956688f7019fbe4dee110b7600349f48da9fff601Erin Dahlgren } 15056688f7019fbe4dee110b7600349f48da9fff601Erin Dahlgren 15156688f7019fbe4dee110b7600349f48da9fff601Erin Dahlgren @Override 15256688f7019fbe4dee110b7600349f48da9fff601Erin Dahlgren public void onPreviewTouched(MotionEvent ev) { 15356688f7019fbe4dee110b7600349f48da9fff601Erin Dahlgren // close options immediately. 15456688f7019fbe4dee110b7600349f48da9fff601Erin Dahlgren closeModeOptionsDelayed(0); 15556688f7019fbe4dee110b7600349f48da9fff601Erin Dahlgren } 15656688f7019fbe4dee110b7600349f48da9fff601Erin Dahlgren 15756688f7019fbe4dee110b7600349f48da9fff601Erin Dahlgren /** 15856688f7019fbe4dee110b7600349f48da9fff601Erin Dahlgren * Schedule (or re-schedule) the options menu to be closed 15956688f7019fbe4dee110b7600349f48da9fff601Erin Dahlgren * after a number of milliseconds. If the options menu 16056688f7019fbe4dee110b7600349f48da9fff601Erin Dahlgren * is already closed, nothing is scheduled. 16156688f7019fbe4dee110b7600349f48da9fff601Erin Dahlgren */ 16256688f7019fbe4dee110b7600349f48da9fff601Erin Dahlgren private void closeModeOptionsDelayed(int milliseconds) { 16356688f7019fbe4dee110b7600349f48da9fff601Erin Dahlgren // Check that the bottom bar options are visible. 16456688f7019fbe4dee110b7600349f48da9fff601Erin Dahlgren if (mOptionsLayout.getVisibility() != View.VISIBLE) { 16556688f7019fbe4dee110b7600349f48da9fff601Erin Dahlgren return; 16656688f7019fbe4dee110b7600349f48da9fff601Erin Dahlgren } 16756688f7019fbe4dee110b7600349f48da9fff601Erin Dahlgren 16856688f7019fbe4dee110b7600349f48da9fff601Erin Dahlgren // Remove queued callbacks. 16956688f7019fbe4dee110b7600349f48da9fff601Erin Dahlgren removeCallbacks(mCloseOptionsRunnable); 17056688f7019fbe4dee110b7600349f48da9fff601Erin Dahlgren 17156688f7019fbe4dee110b7600349f48da9fff601Erin Dahlgren // Close the bottom bar options view in n milliseconds. 17256688f7019fbe4dee110b7600349f48da9fff601Erin Dahlgren postDelayed(mCloseOptionsRunnable, milliseconds); 1734efa8b54c1df4e06f2d3caed2568015a737f9ddaErin Dahlgren } 1744efa8b54c1df4e06f2d3caed2568015a737f9ddaErin Dahlgren 1754efa8b54c1df4e06f2d3caed2568015a737f9ddaErin Dahlgren /** 1764efa8b54c1df4e06f2d3caed2568015a737f9ddaErin Dahlgren * Initializes the bottom bar toggle for switching between 17756688f7019fbe4dee110b7600349f48da9fff601Erin Dahlgren * capture and the bottom bar options. 1784efa8b54c1df4e06f2d3caed2568015a737f9ddaErin Dahlgren */ 17956688f7019fbe4dee110b7600349f48da9fff601Erin Dahlgren public void setupToggle(boolean isCaptureIntent) { 18056688f7019fbe4dee110b7600349f48da9fff601Erin Dahlgren mIsCaptureIntent = isCaptureIntent; 18156688f7019fbe4dee110b7600349f48da9fff601Erin Dahlgren 1824efa8b54c1df4e06f2d3caed2568015a737f9ddaErin Dahlgren // Of type ToggleImageButton because ToggleButton 1834efa8b54c1df4e06f2d3caed2568015a737f9ddaErin Dahlgren // has a non-removable spacing for text on the right-hand side. 18456688f7019fbe4dee110b7600349f48da9fff601Erin Dahlgren mOptionsToggle = (ToggleImageButton) findViewById(R.id.bottombar_options_toggle); 18556688f7019fbe4dee110b7600349f48da9fff601Erin Dahlgren mOptionsToggle.setState(0, false); 18656688f7019fbe4dee110b7600349f48da9fff601Erin Dahlgren mOptionsToggle.setOnStateChangeListener(new ToggleImageButton.OnStateChangeListener() { 1873b92e2f8e6d91af1b83c8bee95bd93e7153b96daSpike Sprague @Override 18856688f7019fbe4dee110b7600349f48da9fff601Erin Dahlgren public void stateChanged(View view, boolean toOptions) { 18956688f7019fbe4dee110b7600349f48da9fff601Erin Dahlgren if (toOptions) { 19056688f7019fbe4dee110b7600349f48da9fff601Erin Dahlgren if (mIsCaptureIntent) { 1913b92e2f8e6d91af1b83c8bee95bd93e7153b96daSpike Sprague hideIntentLayout(); 1923b92e2f8e6d91af1b83c8bee95bd93e7153b96daSpike Sprague } 19356688f7019fbe4dee110b7600349f48da9fff601Erin Dahlgren transitionToOptions(); 1943b92e2f8e6d91af1b83c8bee95bd93e7153b96daSpike Sprague } else { 19556688f7019fbe4dee110b7600349f48da9fff601Erin Dahlgren if (mIsCaptureIntent) { 1963b92e2f8e6d91af1b83c8bee95bd93e7153b96daSpike Sprague transitionToIntentLayout(); 1974efa8b54c1df4e06f2d3caed2568015a737f9ddaErin Dahlgren } else { 1983b92e2f8e6d91af1b83c8bee95bd93e7153b96daSpike Sprague transitionToCapture(); 1994efa8b54c1df4e06f2d3caed2568015a737f9ddaErin Dahlgren } 2004efa8b54c1df4e06f2d3caed2568015a737f9ddaErin Dahlgren } 2013b92e2f8e6d91af1b83c8bee95bd93e7153b96daSpike Sprague } 2023b92e2f8e6d91af1b83c8bee95bd93e7153b96daSpike Sprague }); 20356688f7019fbe4dee110b7600349f48da9fff601Erin Dahlgren mOptionsOverlay.setReferenceViewParent(mOptionsLayout); 2044efa8b54c1df4e06f2d3caed2568015a737f9ddaErin Dahlgren } 2054efa8b54c1df4e06f2d3caed2568015a737f9ddaErin Dahlgren 2064efa8b54c1df4e06f2d3caed2568015a737f9ddaErin Dahlgren /** 2074efa8b54c1df4e06f2d3caed2568015a737f9ddaErin Dahlgren * Hide the intent layout. This is necessary for switching between 20856688f7019fbe4dee110b7600349f48da9fff601Erin Dahlgren * the intent capture layout and the bottom bar options. 2094efa8b54c1df4e06f2d3caed2568015a737f9ddaErin Dahlgren */ 2104efa8b54c1df4e06f2d3caed2568015a737f9ddaErin Dahlgren private void hideIntentLayout() { 2114efa8b54c1df4e06f2d3caed2568015a737f9ddaErin Dahlgren mIntentLayout.setVisibility(View.INVISIBLE); 2124efa8b54c1df4e06f2d3caed2568015a737f9ddaErin Dahlgren } 2134efa8b54c1df4e06f2d3caed2568015a737f9ddaErin Dahlgren 2144efa8b54c1df4e06f2d3caed2568015a737f9ddaErin Dahlgren /** 21556688f7019fbe4dee110b7600349f48da9fff601Erin Dahlgren * Perform a transition from the bottom bar options layout to the 21656688f7019fbe4dee110b7600349f48da9fff601Erin Dahlgren * bottom bar capture layout. 2174efa8b54c1df4e06f2d3caed2568015a737f9ddaErin Dahlgren */ 2184efa8b54c1df4e06f2d3caed2568015a737f9ddaErin Dahlgren private void transitionToCapture() { 21956688f7019fbe4dee110b7600349f48da9fff601Erin Dahlgren mOptionsLayout.setVisibility(View.INVISIBLE); 2204efa8b54c1df4e06f2d3caed2568015a737f9ddaErin Dahlgren mCaptureLayout.setVisibility(View.VISIBLE); 2214efa8b54c1df4e06f2d3caed2568015a737f9ddaErin Dahlgren } 2224efa8b54c1df4e06f2d3caed2568015a737f9ddaErin Dahlgren 2234efa8b54c1df4e06f2d3caed2568015a737f9ddaErin Dahlgren /** 22456688f7019fbe4dee110b7600349f48da9fff601Erin Dahlgren * Perform a transition from the bottom bar capture layout to the 22556688f7019fbe4dee110b7600349f48da9fff601Erin Dahlgren * bottom bar options layout. 2264efa8b54c1df4e06f2d3caed2568015a737f9ddaErin Dahlgren */ 22756688f7019fbe4dee110b7600349f48da9fff601Erin Dahlgren private void transitionToOptions() { 2283b92e2f8e6d91af1b83c8bee95bd93e7153b96daSpike Sprague mCaptureLayout.setVisibility(View.INVISIBLE); 22956688f7019fbe4dee110b7600349f48da9fff601Erin Dahlgren mOptionsLayout.setVisibility(View.VISIBLE); 2304efa8b54c1df4e06f2d3caed2568015a737f9ddaErin Dahlgren } 2314efa8b54c1df4e06f2d3caed2568015a737f9ddaErin Dahlgren 2320744e4ab3ec5f0270bdad33e7c477f52ba680bbdMarco Nelissen /** 2334efa8b54c1df4e06f2d3caed2568015a737f9ddaErin Dahlgren * Perform a transition to the global intent layout. The current 2344efa8b54c1df4e06f2d3caed2568015a737f9ddaErin Dahlgren * layout state of the bottom bar is irrelevant. 2350f3c4b4fc9ac87d7d4c3d04c3cb3426c711f57eaSpike Sprague */ 2364efa8b54c1df4e06f2d3caed2568015a737f9ddaErin Dahlgren public void transitionToIntentLayout() { 2374efa8b54c1df4e06f2d3caed2568015a737f9ddaErin Dahlgren mCaptureLayout.setVisibility(View.VISIBLE); 23856688f7019fbe4dee110b7600349f48da9fff601Erin Dahlgren mOptionsLayout.setVisibility(View.INVISIBLE); 23956688f7019fbe4dee110b7600349f48da9fff601Erin Dahlgren mOptionsOverlay.setVisibility(View.VISIBLE); 2404efa8b54c1df4e06f2d3caed2568015a737f9ddaErin Dahlgren mIntentLayout.setVisibility(View.VISIBLE); 2414efa8b54c1df4e06f2d3caed2568015a737f9ddaErin Dahlgren 2424efa8b54c1df4e06f2d3caed2568015a737f9ddaErin Dahlgren View button; 2434efa8b54c1df4e06f2d3caed2568015a737f9ddaErin Dahlgren button = mIntentLayout.findViewById(R.id.done_button); 2444efa8b54c1df4e06f2d3caed2568015a737f9ddaErin Dahlgren button.setVisibility(View.INVISIBLE); 2454efa8b54c1df4e06f2d3caed2568015a737f9ddaErin Dahlgren button = mIntentLayout.findViewById(R.id.retake_button); 2464efa8b54c1df4e06f2d3caed2568015a737f9ddaErin Dahlgren button.setVisibility(View.INVISIBLE); 2474efa8b54c1df4e06f2d3caed2568015a737f9ddaErin Dahlgren } 2484efa8b54c1df4e06f2d3caed2568015a737f9ddaErin Dahlgren 2494efa8b54c1df4e06f2d3caed2568015a737f9ddaErin Dahlgren /** 2504efa8b54c1df4e06f2d3caed2568015a737f9ddaErin Dahlgren * Perform a transition to the global intent review layout. 2514efa8b54c1df4e06f2d3caed2568015a737f9ddaErin Dahlgren * The current layout state of the bottom bar is irrelevant. 2524efa8b54c1df4e06f2d3caed2568015a737f9ddaErin Dahlgren */ 2534efa8b54c1df4e06f2d3caed2568015a737f9ddaErin Dahlgren public void transitionToIntentReviewLayout() { 2544efa8b54c1df4e06f2d3caed2568015a737f9ddaErin Dahlgren mCaptureLayout.setVisibility(View.INVISIBLE); 25556688f7019fbe4dee110b7600349f48da9fff601Erin Dahlgren mOptionsLayout.setVisibility(View.INVISIBLE); 25656688f7019fbe4dee110b7600349f48da9fff601Erin Dahlgren mOptionsOverlay.setVisibility(View.INVISIBLE); 2574efa8b54c1df4e06f2d3caed2568015a737f9ddaErin Dahlgren 2584efa8b54c1df4e06f2d3caed2568015a737f9ddaErin Dahlgren View button; 2594efa8b54c1df4e06f2d3caed2568015a737f9ddaErin Dahlgren button = mIntentLayout.findViewById(R.id.done_button); 2604efa8b54c1df4e06f2d3caed2568015a737f9ddaErin Dahlgren button.setVisibility(View.VISIBLE); 2614efa8b54c1df4e06f2d3caed2568015a737f9ddaErin Dahlgren button = mIntentLayout.findViewById(R.id.retake_button); 2624efa8b54c1df4e06f2d3caed2568015a737f9ddaErin Dahlgren button.setVisibility(View.VISIBLE); 2634efa8b54c1df4e06f2d3caed2568015a737f9ddaErin Dahlgren mIntentLayout.setVisibility(View.VISIBLE); 2640f3c4b4fc9ac87d7d4c3d04c3cb3426c711f57eaSpike Sprague } 2650f3c4b4fc9ac87d7d4c3d04c3cb3426c711f57eaSpike Sprague 26670da918464276b110c43868caa272c97baadb89eDoris Liu @Override 26770da918464276b110c43868caa272c97baadb89eDoris Liu public void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { 26870da918464276b110c43868caa272c97baadb89eDoris Liu mWidth = MeasureSpec.getSize(widthMeasureSpec); 26970da918464276b110c43868caa272c97baadb89eDoris Liu mHeight = MeasureSpec.getSize(heightMeasureSpec); 27070da918464276b110c43868caa272c97baadb89eDoris Liu if (mWidth == 0 || mHeight == 0) { 27170da918464276b110c43868caa272c97baadb89eDoris Liu return; 27270da918464276b110c43868caa272c97baadb89eDoris Liu } 27370da918464276b110c43868caa272c97baadb89eDoris Liu 27470da918464276b110c43868caa272c97baadb89eDoris Liu if (mOffsetShorterEdge != 0 && mOffsetLongerEdge != 0) { 27570da918464276b110c43868caa272c97baadb89eDoris Liu float previewAspectRatio = 27670da918464276b110c43868caa272c97baadb89eDoris Liu mOffsetLongerEdge / mOffsetShorterEdge; 27770da918464276b110c43868caa272c97baadb89eDoris Liu if (previewAspectRatio < 1.0) { 27870da918464276b110c43868caa272c97baadb89eDoris Liu previewAspectRatio = 1.0f/previewAspectRatio; 27970da918464276b110c43868caa272c97baadb89eDoris Liu } 28070da918464276b110c43868caa272c97baadb89eDoris Liu float screenAspectRatio = (float) mWidth / (float) mHeight; 28170da918464276b110c43868caa272c97baadb89eDoris Liu if (screenAspectRatio < 1.0) { 28270da918464276b110c43868caa272c97baadb89eDoris Liu screenAspectRatio = 1.0f/screenAspectRatio; 28370da918464276b110c43868caa272c97baadb89eDoris Liu } 28470da918464276b110c43868caa272c97baadb89eDoris Liu if (previewAspectRatio >= screenAspectRatio) { 28570da918464276b110c43868caa272c97baadb89eDoris Liu mOverLayBottomBar = true; 28639f8a7647aa4051a1c260b9496c2db82f93f8667Spike Sprague setBackgroundAlpha(128); 28770da918464276b110c43868caa272c97baadb89eDoris Liu } else { 28870da918464276b110c43868caa272c97baadb89eDoris Liu mOverLayBottomBar = false; 28939f8a7647aa4051a1c260b9496c2db82f93f8667Spike Sprague setBackgroundAlpha(255); 29070da918464276b110c43868caa272c97baadb89eDoris Liu } 29170da918464276b110c43868caa272c97baadb89eDoris Liu } 29270da918464276b110c43868caa272c97baadb89eDoris Liu 29370da918464276b110c43868caa272c97baadb89eDoris Liu // Calculates the width and height needed for the bar. 29470da918464276b110c43868caa272c97baadb89eDoris Liu int barWidth, barHeight; 29570da918464276b110c43868caa272c97baadb89eDoris Liu if (mWidth > mHeight) { 2961648c36927501ff32bf2918e8a445118d5208731Erin Dahlgren // TODO: The bottom bar should not need to care about the 2971648c36927501ff32bf2918e8a445118d5208731Erin Dahlgren // the type of its parent. Handle this in the parent layout. 2981648c36927501ff32bf2918e8a445118d5208731Erin Dahlgren ((LinearLayout.LayoutParams) getLayoutParams()).gravity = Gravity.RIGHT; 29970da918464276b110c43868caa272c97baadb89eDoris Liu if ((mOffsetLongerEdge == 0 && mOffsetShorterEdge == 0) || mOverLayBottomBar) { 30070da918464276b110c43868caa272c97baadb89eDoris Liu barWidth = mOptimalHeight; 30170da918464276b110c43868caa272c97baadb89eDoris Liu barHeight = mHeight; 30270da918464276b110c43868caa272c97baadb89eDoris Liu } else { 30370da918464276b110c43868caa272c97baadb89eDoris Liu barWidth = (int) (mWidth - mOffsetLongerEdge); 30470da918464276b110c43868caa272c97baadb89eDoris Liu barHeight = mHeight; 30570da918464276b110c43868caa272c97baadb89eDoris Liu } 3060744e4ab3ec5f0270bdad33e7c477f52ba680bbdMarco Nelissen } else { 3071648c36927501ff32bf2918e8a445118d5208731Erin Dahlgren ((LinearLayout.LayoutParams) getLayoutParams()).gravity = Gravity.BOTTOM; 30870da918464276b110c43868caa272c97baadb89eDoris Liu if ((mOffsetLongerEdge == 0 && mOffsetShorterEdge == 0) || mOverLayBottomBar) { 30970da918464276b110c43868caa272c97baadb89eDoris Liu barWidth = mWidth; 31070da918464276b110c43868caa272c97baadb89eDoris Liu barHeight = mOptimalHeight; 31170da918464276b110c43868caa272c97baadb89eDoris Liu } else { 31270da918464276b110c43868caa272c97baadb89eDoris Liu barWidth = mWidth; 31370da918464276b110c43868caa272c97baadb89eDoris Liu barHeight = (int) (mHeight - mOffsetLongerEdge); 31470da918464276b110c43868caa272c97baadb89eDoris Liu } 3150744e4ab3ec5f0270bdad33e7c477f52ba680bbdMarco Nelissen } 31639f8a7647aa4051a1c260b9496c2db82f93f8667Spike Sprague 31739f8a7647aa4051a1c260b9496c2db82f93f8667Spike Sprague mCirclePath.addCircle( 31839f8a7647aa4051a1c260b9496c2db82f93f8667Spike Sprague barWidth/2, 31939f8a7647aa4051a1c260b9496c2db82f93f8667Spike Sprague barHeight/2, 32039f8a7647aa4051a1c260b9496c2db82f93f8667Spike Sprague (int)(diagonalLength(barWidth, barHeight)/2), 32139f8a7647aa4051a1c260b9496c2db82f93f8667Spike Sprague Path.Direction.CW); 32239f8a7647aa4051a1c260b9496c2db82f93f8667Spike Sprague 32370da918464276b110c43868caa272c97baadb89eDoris Liu super.onMeasure(MeasureSpec.makeMeasureSpec(barWidth, MeasureSpec.EXACTLY), 32470da918464276b110c43868caa272c97baadb89eDoris Liu MeasureSpec.makeMeasureSpec(barHeight, MeasureSpec.EXACTLY)); 32570da918464276b110c43868caa272c97baadb89eDoris Liu } 32670da918464276b110c43868caa272c97baadb89eDoris Liu 32770da918464276b110c43868caa272c97baadb89eDoris Liu private void adjustBottomBar(float scaledTextureWidth, 32870da918464276b110c43868caa272c97baadb89eDoris Liu float scaledTextureHeight) { 32970da918464276b110c43868caa272c97baadb89eDoris Liu setOffset(scaledTextureWidth, scaledTextureHeight); 33070da918464276b110c43868caa272c97baadb89eDoris Liu } 33170da918464276b110c43868caa272c97baadb89eDoris Liu 33270da918464276b110c43868caa272c97baadb89eDoris Liu @Override 333a1ec04a9f9526418f5cb17a5afbfc48aca1e02d0Doris Liu public void onPreviewAreaSizeChanged(RectF previewArea) { 334a1ec04a9f9526418f5cb17a5afbfc48aca1e02d0Doris Liu adjustBottomBar(previewArea.width(), previewArea.height()); 33570da918464276b110c43868caa272c97baadb89eDoris Liu } 33670da918464276b110c43868caa272c97baadb89eDoris Liu 33770da918464276b110c43868caa272c97baadb89eDoris Liu private void setOffset(float scaledTextureWidth, float scaledTextureHeight) { 33870da918464276b110c43868caa272c97baadb89eDoris Liu float offsetLongerEdge, offsetShorterEdge; 33970da918464276b110c43868caa272c97baadb89eDoris Liu if (scaledTextureHeight > scaledTextureWidth) { 34070da918464276b110c43868caa272c97baadb89eDoris Liu offsetLongerEdge = scaledTextureHeight; 34170da918464276b110c43868caa272c97baadb89eDoris Liu offsetShorterEdge = scaledTextureWidth; 3420744e4ab3ec5f0270bdad33e7c477f52ba680bbdMarco Nelissen } else { 34370da918464276b110c43868caa272c97baadb89eDoris Liu offsetLongerEdge = scaledTextureWidth; 34470da918464276b110c43868caa272c97baadb89eDoris Liu offsetShorterEdge = scaledTextureHeight; 34570da918464276b110c43868caa272c97baadb89eDoris Liu } 34670da918464276b110c43868caa272c97baadb89eDoris Liu if (mOffsetLongerEdge != offsetLongerEdge || mOffsetShorterEdge != offsetShorterEdge) { 34770da918464276b110c43868caa272c97baadb89eDoris Liu mOffsetLongerEdge = offsetLongerEdge; 34870da918464276b110c43868caa272c97baadb89eDoris Liu mOffsetShorterEdge = offsetShorterEdge; 34970da918464276b110c43868caa272c97baadb89eDoris Liu requestLayout(); 3500744e4ab3ec5f0270bdad33e7c477f52ba680bbdMarco Nelissen } 3510744e4ab3ec5f0270bdad33e7c477f52ba680bbdMarco Nelissen } 3520744e4ab3ec5f0270bdad33e7c477f52ba680bbdMarco Nelissen 3530744e4ab3ec5f0270bdad33e7c477f52ba680bbdMarco Nelissen @Override 3540744e4ab3ec5f0270bdad33e7c477f52ba680bbdMarco Nelissen protected void onConfigurationChanged(Configuration config) { 3550744e4ab3ec5f0270bdad33e7c477f52ba680bbdMarco Nelissen super.onConfigurationChanged(config); 3560744e4ab3ec5f0270bdad33e7c477f52ba680bbdMarco Nelissen } 3570744e4ab3ec5f0270bdad33e7c477f52ba680bbdMarco Nelissen 358e3b0e946924e45f6788db69aaa8f48a2d81031f0Spike Sprague // prevent touches on bottom bar (not its children) 359e3b0e946924e45f6788db69aaa8f48a2d81031f0Spike Sprague // from triggering a touch event on preview area 360e3b0e946924e45f6788db69aaa8f48a2d81031f0Spike Sprague @Override 361e3b0e946924e45f6788db69aaa8f48a2d81031f0Spike Sprague public boolean onTouchEvent(MotionEvent event) { 362e3b0e946924e45f6788db69aaa8f48a2d81031f0Spike Sprague return true; 363e3b0e946924e45f6788db69aaa8f48a2d81031f0Spike Sprague } 36439f8a7647aa4051a1c260b9496c2db82f93f8667Spike Sprague 36539f8a7647aa4051a1c260b9496c2db82f93f8667Spike Sprague @Override 36639f8a7647aa4051a1c260b9496c2db82f93f8667Spike Sprague public void onDraw(Canvas canvas) { 36739f8a7647aa4051a1c260b9496c2db82f93f8667Spike Sprague canvas.drawPath(mCirclePath, mCirclePaint); 36839f8a7647aa4051a1c260b9496c2db82f93f8667Spike Sprague 36939f8a7647aa4051a1c260b9496c2db82f93f8667Spike Sprague super.onDraw(canvas); 37039f8a7647aa4051a1c260b9496c2db82f93f8667Spike Sprague } 37139f8a7647aa4051a1c260b9496c2db82f93f8667Spike Sprague 37239f8a7647aa4051a1c260b9496c2db82f93f8667Spike Sprague @Override 37339f8a7647aa4051a1c260b9496c2db82f93f8667Spike Sprague public void setBackgroundColor(int color) { 37439f8a7647aa4051a1c260b9496c2db82f93f8667Spike Sprague mBackgroundColor = color; 375b92910e04c4da91fc4ea5a9484b83f9ecba1c896Spike Sprague setPaintColor(mBackgroundAlpha, mBackgroundColor); 376b92910e04c4da91fc4ea5a9484b83f9ecba1c896Spike Sprague } 377b92910e04c4da91fc4ea5a9484b83f9ecba1c896Spike Sprague 378b92910e04c4da91fc4ea5a9484b83f9ecba1c896Spike Sprague public void setBackgroundPressedColor(int color) { 379b92910e04c4da91fc4ea5a9484b83f9ecba1c896Spike Sprague mBackgroundPressedColor = color; 38039f8a7647aa4051a1c260b9496c2db82f93f8667Spike Sprague } 38139f8a7647aa4051a1c260b9496c2db82f93f8667Spike Sprague 38239f8a7647aa4051a1c260b9496c2db82f93f8667Spike Sprague public void setBackgroundAlpha(int alpha) { 383b92910e04c4da91fc4ea5a9484b83f9ecba1c896Spike Sprague mBackgroundAlpha = alpha; 384b92910e04c4da91fc4ea5a9484b83f9ecba1c896Spike Sprague setPaintColor(mBackgroundAlpha, mBackgroundColor); 38539f8a7647aa4051a1c260b9496c2db82f93f8667Spike Sprague } 38639f8a7647aa4051a1c260b9496c2db82f93f8667Spike Sprague 38739f8a7647aa4051a1c260b9496c2db82f93f8667Spike Sprague private double diagonalLength(double w, double h) { 38839f8a7647aa4051a1c260b9496c2db82f93f8667Spike Sprague return Math.sqrt((w*w) + (h*h)); 38939f8a7647aa4051a1c260b9496c2db82f93f8667Spike Sprague } 39039f8a7647aa4051a1c260b9496c2db82f93f8667Spike Sprague private double diagonalLength() { 39139f8a7647aa4051a1c260b9496c2db82f93f8667Spike Sprague return diagonalLength(getWidth(), getHeight()); 39239f8a7647aa4051a1c260b9496c2db82f93f8667Spike Sprague } 39339f8a7647aa4051a1c260b9496c2db82f93f8667Spike Sprague 39439f8a7647aa4051a1c260b9496c2db82f93f8667Spike Sprague private TransitionDrawable crossfadeDrawable(Drawable from, Drawable to) { 39539f8a7647aa4051a1c260b9496c2db82f93f8667Spike Sprague Drawable [] arrayDrawable = new Drawable[2]; 39639f8a7647aa4051a1c260b9496c2db82f93f8667Spike Sprague arrayDrawable[0] = from; 39739f8a7647aa4051a1c260b9496c2db82f93f8667Spike Sprague arrayDrawable[1] = to; 39839f8a7647aa4051a1c260b9496c2db82f93f8667Spike Sprague TransitionDrawable transitionDrawable = new TransitionDrawable(arrayDrawable); 39939f8a7647aa4051a1c260b9496c2db82f93f8667Spike Sprague transitionDrawable.setCrossFadeEnabled(true); 40039f8a7647aa4051a1c260b9496c2db82f93f8667Spike Sprague return transitionDrawable; 40139f8a7647aa4051a1c260b9496c2db82f93f8667Spike Sprague } 40239f8a7647aa4051a1c260b9496c2db82f93f8667Spike Sprague 40339f8a7647aa4051a1c260b9496c2db82f93f8667Spike Sprague /** 40439f8a7647aa4051a1c260b9496c2db82f93f8667Spike Sprague * Set the shutter button's icon resource 40539f8a7647aa4051a1c260b9496c2db82f93f8667Spike Sprague */ 40639f8a7647aa4051a1c260b9496c2db82f93f8667Spike Sprague public void setShutterButtonIcon(int resId) { 40739f8a7647aa4051a1c260b9496c2db82f93f8667Spike Sprague mShutterButton.setImageResource(resId); 40839f8a7647aa4051a1c260b9496c2db82f93f8667Spike Sprague } 40939f8a7647aa4051a1c260b9496c2db82f93f8667Spike Sprague 41039f8a7647aa4051a1c260b9496c2db82f93f8667Spike Sprague /** 41139f8a7647aa4051a1c260b9496c2db82f93f8667Spike Sprague * Animates bar to a single stop button 41239f8a7647aa4051a1c260b9496c2db82f93f8667Spike Sprague */ 41339f8a7647aa4051a1c260b9496c2db82f93f8667Spike Sprague public void animateToCircle(int resId) { 41439f8a7647aa4051a1c260b9496c2db82f93f8667Spike Sprague final ValueAnimator radiusAnimator = ValueAnimator.ofFloat( 41539f8a7647aa4051a1c260b9496c2db82f93f8667Spike Sprague (float) diagonalLength()/2, 41639f8a7647aa4051a1c260b9496c2db82f93f8667Spike Sprague CIRCLE_RADIUS); 41739f8a7647aa4051a1c260b9496c2db82f93f8667Spike Sprague radiusAnimator.setDuration(CIRCLE_ANIM_DURATION_MS); 41839f8a7647aa4051a1c260b9496c2db82f93f8667Spike Sprague radiusAnimator.setInterpolator(Gusterpolator.INSTANCE); 41939f8a7647aa4051a1c260b9496c2db82f93f8667Spike Sprague 42039f8a7647aa4051a1c260b9496c2db82f93f8667Spike Sprague radiusAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { 42139f8a7647aa4051a1c260b9496c2db82f93f8667Spike Sprague @Override 42239f8a7647aa4051a1c260b9496c2db82f93f8667Spike Sprague public void onAnimationUpdate(ValueAnimator animation) { 42339f8a7647aa4051a1c260b9496c2db82f93f8667Spike Sprague mCirclePath.reset(); 42439f8a7647aa4051a1c260b9496c2db82f93f8667Spike Sprague mCirclePath.addCircle( 42539f8a7647aa4051a1c260b9496c2db82f93f8667Spike Sprague getWidth()/2, 42639f8a7647aa4051a1c260b9496c2db82f93f8667Spike Sprague getHeight()/2, 42739f8a7647aa4051a1c260b9496c2db82f93f8667Spike Sprague (Float) animation.getAnimatedValue(), 42839f8a7647aa4051a1c260b9496c2db82f93f8667Spike Sprague Path.Direction.CW); 42939f8a7647aa4051a1c260b9496c2db82f93f8667Spike Sprague 43039f8a7647aa4051a1c260b9496c2db82f93f8667Spike Sprague invalidate(); 43139f8a7647aa4051a1c260b9496c2db82f93f8667Spike Sprague } 43239f8a7647aa4051a1c260b9496c2db82f93f8667Spike Sprague }); 43339f8a7647aa4051a1c260b9496c2db82f93f8667Spike Sprague 43439f8a7647aa4051a1c260b9496c2db82f93f8667Spike Sprague TransitionDrawable transitionDrawable = crossfadeDrawable( 43539f8a7647aa4051a1c260b9496c2db82f93f8667Spike Sprague mShutterButton.getDrawable(), 43639f8a7647aa4051a1c260b9496c2db82f93f8667Spike Sprague getResources().getDrawable(resId)); 43739f8a7647aa4051a1c260b9496c2db82f93f8667Spike Sprague mShutterButton.setImageDrawable(transitionDrawable); 43839f8a7647aa4051a1c260b9496c2db82f93f8667Spike Sprague 43939f8a7647aa4051a1c260b9496c2db82f93f8667Spike Sprague View optionsOverlay = findViewById(R.id.bottombar_options_overlay); 44039f8a7647aa4051a1c260b9496c2db82f93f8667Spike Sprague optionsOverlay.setVisibility(View.INVISIBLE); 44139f8a7647aa4051a1c260b9496c2db82f93f8667Spike Sprague 44239f8a7647aa4051a1c260b9496c2db82f93f8667Spike Sprague 44339f8a7647aa4051a1c260b9496c2db82f93f8667Spike Sprague transitionDrawable.startTransition(CIRCLE_ANIM_DURATION_MS); 44439f8a7647aa4051a1c260b9496c2db82f93f8667Spike Sprague radiusAnimator.start(); 44539f8a7647aa4051a1c260b9496c2db82f93f8667Spike Sprague } 44639f8a7647aa4051a1c260b9496c2db82f93f8667Spike Sprague 44739f8a7647aa4051a1c260b9496c2db82f93f8667Spike Sprague /** 44839f8a7647aa4051a1c260b9496c2db82f93f8667Spike Sprague * Animates bar to full width / length with video capture icon 44939f8a7647aa4051a1c260b9496c2db82f93f8667Spike Sprague */ 45039f8a7647aa4051a1c260b9496c2db82f93f8667Spike Sprague public void animateToFullSize(int resId) { 45139f8a7647aa4051a1c260b9496c2db82f93f8667Spike Sprague final ValueAnimator radiusAnimator = ValueAnimator.ofFloat( 45239f8a7647aa4051a1c260b9496c2db82f93f8667Spike Sprague CIRCLE_RADIUS, 45339f8a7647aa4051a1c260b9496c2db82f93f8667Spike Sprague (float) diagonalLength()/2); 45439f8a7647aa4051a1c260b9496c2db82f93f8667Spike Sprague radiusAnimator.setDuration(CIRCLE_ANIM_DURATION_MS); 45539f8a7647aa4051a1c260b9496c2db82f93f8667Spike Sprague radiusAnimator.setInterpolator(Gusterpolator.INSTANCE); 45639f8a7647aa4051a1c260b9496c2db82f93f8667Spike Sprague radiusAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { 45739f8a7647aa4051a1c260b9496c2db82f93f8667Spike Sprague @Override 45839f8a7647aa4051a1c260b9496c2db82f93f8667Spike Sprague public void onAnimationUpdate(ValueAnimator animation) { 45939f8a7647aa4051a1c260b9496c2db82f93f8667Spike Sprague mCirclePath.reset(); 46039f8a7647aa4051a1c260b9496c2db82f93f8667Spike Sprague mCirclePath.addCircle( 46139f8a7647aa4051a1c260b9496c2db82f93f8667Spike Sprague getWidth()/2, 46239f8a7647aa4051a1c260b9496c2db82f93f8667Spike Sprague getHeight()/2, 46339f8a7647aa4051a1c260b9496c2db82f93f8667Spike Sprague (Float) animation.getAnimatedValue(), 46439f8a7647aa4051a1c260b9496c2db82f93f8667Spike Sprague Path.Direction.CW); 46539f8a7647aa4051a1c260b9496c2db82f93f8667Spike Sprague 46639f8a7647aa4051a1c260b9496c2db82f93f8667Spike Sprague invalidate(); 46739f8a7647aa4051a1c260b9496c2db82f93f8667Spike Sprague } 46839f8a7647aa4051a1c260b9496c2db82f93f8667Spike Sprague }); 46939f8a7647aa4051a1c260b9496c2db82f93f8667Spike Sprague radiusAnimator.addListener(new AnimatorListenerAdapter() { 47039f8a7647aa4051a1c260b9496c2db82f93f8667Spike Sprague @Override 47139f8a7647aa4051a1c260b9496c2db82f93f8667Spike Sprague public void onAnimationEnd(Animator animation) { 47239f8a7647aa4051a1c260b9496c2db82f93f8667Spike Sprague View optionsOverlay = findViewById(R.id.bottombar_options_overlay); 47339f8a7647aa4051a1c260b9496c2db82f93f8667Spike Sprague optionsOverlay.setVisibility(View.VISIBLE); 47439f8a7647aa4051a1c260b9496c2db82f93f8667Spike Sprague } 47539f8a7647aa4051a1c260b9496c2db82f93f8667Spike Sprague }); 47639f8a7647aa4051a1c260b9496c2db82f93f8667Spike Sprague 47739f8a7647aa4051a1c260b9496c2db82f93f8667Spike Sprague TransitionDrawable transitionDrawable = crossfadeDrawable( 47839f8a7647aa4051a1c260b9496c2db82f93f8667Spike Sprague mShutterButton.getDrawable(), 47939f8a7647aa4051a1c260b9496c2db82f93f8667Spike Sprague getResources().getDrawable(resId)); 48039f8a7647aa4051a1c260b9496c2db82f93f8667Spike Sprague mShutterButton.setImageDrawable(transitionDrawable); 48139f8a7647aa4051a1c260b9496c2db82f93f8667Spike Sprague 48239f8a7647aa4051a1c260b9496c2db82f93f8667Spike Sprague transitionDrawable.startTransition(CIRCLE_ANIM_DURATION_MS); 48339f8a7647aa4051a1c260b9496c2db82f93f8667Spike Sprague radiusAnimator.start(); 48439f8a7647aa4051a1c260b9496c2db82f93f8667Spike Sprague } 4850744e4ab3ec5f0270bdad33e7c477f52ba680bbdMarco Nelissen} 486