10eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer/*
20eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer * Copyright (c) 2016, The Android Open Source Project
30eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer *
40eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer * Licensed under the Apache License, Version 2.0 (the "License");
50eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer * you may not use this file except in compliance with the License.
60eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer * You may obtain a copy of the License at
70eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer *
80eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer *     http://www.apache.org/licenses/LICENSE-2.0
90eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer *
100eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer * Unless required by applicable law or agreed to in writing, software
110eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer * distributed under the License is distributed on an "AS IS" BASIS,
120eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
130eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer * See the License for the specific language governing permissions and
140eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer * limitations under the License.
150eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer */
160eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyerpackage com.android.car.hvac.ui;
170eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer
180eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyerimport android.animation.Animator;
190eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyerimport android.animation.AnimatorSet;
200eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyerimport android.animation.ObjectAnimator;
210eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyerimport android.animation.ValueAnimator;
220eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyerimport android.content.Context;
230eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyerimport android.content.res.Resources;
240eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyerimport android.graphics.drawable.GradientDrawable;
250eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyerimport android.util.AttributeSet;
260eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyerimport android.view.View;
270eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyerimport android.widget.FrameLayout;
280eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyerimport android.widget.ImageView;
290eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyerimport android.widget.TextView;
300eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyerimport com.android.car.hvac.R;
310eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer
320eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyerimport java.util.ArrayList;
330eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyerimport java.util.List;
340eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer
350eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer/**
360eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer * An expandable temperature control bar. Note this UI is meant to only support Fahrenheit.
370eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer */
380eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyerpublic class TemperatureBarOverlay extends FrameLayout {
390eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer    /**
400eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer     * A listener that observes clicks on the temperature bar.
410eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer     */
420eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer    public interface TemperatureAdjustClickListener {
430eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer        void onTemperatureChanged(int temperature);
440eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer    }
450eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer
460eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer    private static final int EXPAND_ANIMATION_TIME_MS = 500;
470eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer    private static final int COLLAPSE_ANIMATION_TIME_MS = 200;
480eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer
490eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer    private static final int TEXT_ALPHA_ANIMATION_TIME_DELAY_MS = 400;
500eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer    private static final int TEXT_ALPHA_FADE_OUT_ANIMATION_TIME_MS = 100;
510eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer    private static final int TEXT_ALPHA_FADE_IN_ANIMATION_TIME_MS = 300;
520eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer
530eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer    private static final int COLOR_CHANGE_ANIMATION_TIME_MS = 200;
540eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer
550eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer    private static final float BUTTON_ALPHA_COLLAPSED = 0f;
560eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer    private static final float BUTTON_ALPHA_EXPANDED = 1.0f;
570eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer
580eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer    private static final int DEFAULT_TEMPERATURE = 32;
590eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer    private static final int MAX_TEMPERATURE = 85;
600eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer    private static final int MIN_TEMPERATURE = 60;
610eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer
620eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer    private String mInvalidTemperature;
630eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer
640eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer    private int mTempColor1;
650eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer    private int mTempColor2;
660eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer    private int mTempColor3;
670eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer    private int mTempColor4;
680eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer    private int mTempColor5;
690eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer
700eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer    private int mOffColor;
710eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer
720eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer    private ImageView mIncreaseButton;
730eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer    private ImageView mDecreaseButton;
740eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer    private TextView mText;
750eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer    private TextView mFloatingText;
760eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer    private TextView mOffText;
770eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer    private View mTemperatureBar;
780eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer    private View mCloseButton;
790eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer
800eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer    private int mTemperature = DEFAULT_TEMPERATURE;
810eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer
820eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer    private int mCollapsedWidth;
830eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer    private int mExpandedWidth;
840eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer    private int mCollapsedHeight;
850eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer    private int mExpandedHeight;
860eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer    private int mCollapsedYShift;
870eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer    private int mExpandedYShift;
880eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer
890eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer    private boolean mIsOpen;
900eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer    private boolean mIsOn = true;
910eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer
920eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer    private TemperatureAdjustClickListener mListener;
930eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer
940eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer    public TemperatureBarOverlay(Context context) {
950eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer        super(context);
960eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer    }
970eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer
980eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer    public TemperatureBarOverlay(Context context, AttributeSet attrs) {
990eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer        super(context, attrs);
1000eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer    }
1010eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer
1020eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer    public TemperatureBarOverlay(Context context, AttributeSet attrs, int defStyleAttr) {
1030eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer        super(context, attrs, defStyleAttr);
1040eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer    }
1050eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer
1060eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer    @Override
1070eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer    protected void onFinishInflate() {
1080eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer        super.onFinishInflate();
1090eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer
1100eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer        Resources res = getResources();
1110eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer
1120eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer        mCollapsedHeight = res.getDimensionPixelSize(R.dimen.temperature_bar_collapsed_height);
1130eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer        mExpandedHeight = res.getDimensionPixelSize(R.dimen.temperature_bar_expanded_height);
1140eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer        // Push the collapsed circle all the way down to the bottom of the screen and leave
1150eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer        // half of it visible.
1160eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer        mCollapsedYShift
1170eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer                = res.getDimensionPixelSize(R.dimen.car_hvac_panel_full_expanded_height)
1180eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer                - (mCollapsedHeight / 2);
1190eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer        mExpandedYShift = res.getDimensionPixelSize(R.dimen.hvac_panel_row_margin);
1200eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer
1210eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer        mCollapsedWidth = res.getDimensionPixelSize(R.dimen.temperature_bar_width_collapsed);
1220eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer        mExpandedWidth = res.getDimensionPixelSize(R.dimen.temperature_bar_width_expanded);
1230eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer
1240eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer        mInvalidTemperature = getContext().getString(R.string.hvac_invalid_temperature);
1250eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer
1260eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer        mTempColor1 = res.getColor(R.color.temperature_1);
1270eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer        mTempColor2 = res.getColor(R.color.temperature_2);
1280eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer        mTempColor3 = res.getColor(R.color.temperature_3);
1290eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer        mTempColor4 = res.getColor(R.color.temperature_4);
1300eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer        mTempColor5 = res.getColor(R.color.temperature_5);
1310eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer
1320eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer        mOffColor = res.getColor(R.color.hvac_temperature_off_text_bg_color);
1330eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer
1340eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer        mIncreaseButton = (ImageView) findViewById(R.id.increase_button);
1350eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer        mDecreaseButton = (ImageView) findViewById(R.id.decrease_button);
1360eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer
1370eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer        mFloatingText = (TextView) findViewById(R.id.floating_temperature_text);
1380eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer        mText = (TextView) findViewById(R.id.temperature_text);
1390eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer        mOffText = (TextView) findViewById(R.id.temperature_off_text);
1400eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer
1410eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer        mTemperatureBar = findViewById(R.id.temperature_bar);
1420eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer        mTemperatureBar.setTranslationY(mCollapsedYShift);
1430eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer
1440eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer        mCloseButton = findViewById(R.id.close_button);
1450eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer
1460eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer        mText.setText(getContext().getString(R.string.hvac_temperature_template,
1470eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer                mInvalidTemperature));
1480eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer        mFloatingText.setText(getContext()
1490eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer                .getString(R.string.hvac_temperature_template,
1500eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer                        mInvalidTemperature));
1510eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer
1520eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer        mIncreaseButton.setOnTouchListener(new PressAndHoldTouchListener(temperatureClickListener));
1530eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer        mDecreaseButton.setOnTouchListener(new PressAndHoldTouchListener(temperatureClickListener));
1540eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer
1550eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer        if (!mIsOpen) {
1560eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer            mIncreaseButton.setAlpha(BUTTON_ALPHA_COLLAPSED);
1570eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer            mDecreaseButton.setAlpha(BUTTON_ALPHA_COLLAPSED);
1580eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer            mText.setAlpha(BUTTON_ALPHA_COLLAPSED);
1590eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer
1600eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer            mDecreaseButton.setVisibility(GONE);
1610eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer            mIncreaseButton.setVisibility(GONE);
1620eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer            mText.setVisibility(GONE);
1630eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer        }
1640eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer    }
1650eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer
1660eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer    public void setTemperatureChangeListener(TemperatureAdjustClickListener listener) {
1670eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer        mListener =  listener;
1680eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer    }
1690eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer
1700eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer    public void setBarOnClickListener(OnClickListener l) {
1710eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer        mFloatingText.setOnClickListener(l);
1720eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer        mTemperatureBar.setOnClickListener(l);
1730eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer    }
1740eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer
1750eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer    public void setCloseButtonOnClickListener(OnClickListener l) {
1760eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer        mCloseButton.setOnClickListener(l);
1770eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer    }
1780eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer
1790eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer    public AnimatorSet getExpandAnimatons() {
1800eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer        List<Animator> list = new ArrayList();
1810eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer        AnimatorSet animation = new AnimatorSet();
1820eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer        if (mIsOpen) {
1830eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer            return animation;
1840eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer        }
1850eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer
1860eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer        list.add(getAlphaAnimator(mIncreaseButton, false /* fade */, EXPAND_ANIMATION_TIME_MS));
1870eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer        list.add(getAlphaAnimator(mDecreaseButton, false /* fade */, EXPAND_ANIMATION_TIME_MS));
1880eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer        list.add(getAlphaAnimator(mText, false /* fade */, EXPAND_ANIMATION_TIME_MS));
1890eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer        list.add(getAlphaAnimator(mFloatingText, true /* fade */,
1900eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer                TEXT_ALPHA_FADE_OUT_ANIMATION_TIME_MS));
1910eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer
1920eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer        ValueAnimator widthAnimator = new ValueAnimator().ofInt(mCollapsedWidth, mExpandedWidth)
1930eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer                .setDuration(EXPAND_ANIMATION_TIME_MS);
1940eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer        widthAnimator.addUpdateListener(mWidthUpdateListener);
1950eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer        list.add(widthAnimator);
1960eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer
1970eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer        ValueAnimator heightAnimator = new ValueAnimator().ofInt(mCollapsedHeight,
1980eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer                mExpandedHeight)
1990eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer                .setDuration(EXPAND_ANIMATION_TIME_MS);
2000eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer        heightAnimator.addUpdateListener(mHeightUpdateListener);
2010eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer        list.add(heightAnimator);
2020eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer
2030eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer
2040eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer        ValueAnimator translationYAnimator
2050eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer                = new ValueAnimator().ofFloat(mCollapsedYShift, mExpandedYShift);
2060eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer        translationYAnimator.addUpdateListener(mTranslationYListener);
2070eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer        list.add(translationYAnimator);
2080eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer
2090eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer        animation.playTogether(list);
2100eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer        animation.addListener(mStateListener);
2110eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer
2120eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer        return animation;
2130eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer    }
2140eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer
2150eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer    public AnimatorSet getCollapseAnimations() {
2160eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer
2170eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer        List<Animator> list = new ArrayList();
2180eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer        AnimatorSet animation = new AnimatorSet();
2190eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer
2200eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer        if (!mIsOpen) {
2210eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer            return animation;
2220eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer        }
2230eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer        list.add(getAlphaAnimator(mIncreaseButton, true /* fade */, COLLAPSE_ANIMATION_TIME_MS));
2240eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer        list.add(getAlphaAnimator(mDecreaseButton, true /* fade */, COLLAPSE_ANIMATION_TIME_MS));
2250eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer        list.add(getAlphaAnimator(mText, true /* fade */, COLLAPSE_ANIMATION_TIME_MS));
2260eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer
2270eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer        ObjectAnimator floatingTextAnimator = getAlphaAnimator(mFloatingText,
2280eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer                false /* fade */, TEXT_ALPHA_FADE_IN_ANIMATION_TIME_MS);
2290eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer        floatingTextAnimator.setStartDelay(TEXT_ALPHA_ANIMATION_TIME_DELAY_MS);
2300eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer
2310eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer        list.add(floatingTextAnimator);
2320eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer
2330eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer        ValueAnimator widthAnimator = new ValueAnimator().ofInt(mExpandedWidth, mCollapsedWidth)
2340eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer                .setDuration(COLLAPSE_ANIMATION_TIME_MS);
2350eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer        widthAnimator.addUpdateListener(mWidthUpdateListener);
2360eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer        list.add(widthAnimator);
2370eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer
2380eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer        ValueAnimator heightAnimator = new ValueAnimator().ofInt(mExpandedHeight, mCollapsedHeight)
2390eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer                .setDuration(COLLAPSE_ANIMATION_TIME_MS);
2400eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer        heightAnimator.addUpdateListener(mHeightUpdateListener);
2410eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer        list.add(heightAnimator);
2420eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer
2430eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer        ValueAnimator translationYAnimator
2440eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer                = new ValueAnimator().ofFloat(mExpandedYShift, mCollapsedYShift);
2450eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer        translationYAnimator.addUpdateListener(mTranslationYListener);
2460eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer        list.add(translationYAnimator);
2470eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer
2480eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer        animation.playTogether(list);
2490eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer        animation.addListener(mStateListener);
2500eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer
2510eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer        return animation;
2520eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer    }
2530eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer
2540eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer    private ValueAnimator.AnimatorListener mStateListener = new ValueAnimator.AnimatorListener() {
2550eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer        @Override
2560eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer        public void onAnimationStart(Animator animation) {
2570eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer            if (!mIsOpen) {
2580eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer                mDecreaseButton.setVisibility(VISIBLE);
2590eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer                mIncreaseButton.setVisibility(VISIBLE);
2600eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer                mText.setVisibility(VISIBLE);
2610eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer                mCloseButton.setVisibility(VISIBLE);
2620eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer            } else {
2630eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer                mCloseButton.setVisibility(GONE);
2640eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer            }
2650eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer        }
2660eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer
2670eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer        @Override
2680eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer        public void onAnimationEnd(Animator animation) {
2690eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer            if (mIsOpen) {
2700eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer                //Finished closing, make sure the buttons are now gone,
2710eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer                //so they are no longer touchable
2720eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer                mDecreaseButton.setVisibility(GONE);
2730eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer                mIncreaseButton.setVisibility(GONE);
2740eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer                mText.setVisibility(GONE);
2750eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer                mIsOpen = false;
2760eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer            } else {
2770eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer                //Finished opening
2780eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer                mIsOpen = true;
2790eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer            }
2800eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer        }
2810eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer
2820eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer        @Override
2830eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer        public void onAnimationCancel(Animator animation) {
2840eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer        }
2850eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer
2860eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer        @Override
2870eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer        public void onAnimationRepeat(Animator animation) {
2880eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer        }
2890eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer    };
2900eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer
2910eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer    private void changeTemperatureColor(int startColor, int endColor) {
2920eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer        if (endColor != startColor) {
2930eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer            ValueAnimator animator = ValueAnimator.ofArgb(startColor, endColor);
2940eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer            animator.addUpdateListener(mTemperatureColorListener);
2950eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer            animator.setDuration(COLOR_CHANGE_ANIMATION_TIME_MS);
2960eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer            animator.start();
2970eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer        } else {
2980eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer            ((GradientDrawable) mTemperatureBar.getBackground()).setColor(endColor);
2990eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer        }
3000eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer    }
3010eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer
3020eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer    private final View.OnClickListener temperatureClickListener = new View.OnClickListener() {
3030eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer        @Override
3040eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer        public void onClick(View v) {
3050eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer            int startColor = getTemperatureColor(mTemperature);
3060eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer
3070eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer            if (v == mIncreaseButton && mTemperature < MAX_TEMPERATURE) {
3080eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer                mTemperature++;
3090eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer            } else if (v == mDecreaseButton && mTemperature > MIN_TEMPERATURE) {
3100eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer                mTemperature--;
3110eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer            }
3120eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer            int endColor = getTemperatureColor(mTemperature);
3130eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer            changeTemperatureColor(startColor, endColor);
3140eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer
3150eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer            mText.setText(getContext().getString(R.string.hvac_temperature_template, mTemperature));
3160eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer            mFloatingText.setText(getContext()
3170eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer                    .getString(R.string.hvac_temperature_template, mTemperature));
3180eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer            mListener.onTemperatureChanged(mTemperature);
3190eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer        }
3200eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer    };
3210eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer
3220eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer    public void setTemperature(int temperature) {
3230eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer        int startColor = getTemperatureColor(mTemperature);
3240eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer        int endColor = getTemperatureColor(temperature);
3250eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer        mTemperature = temperature;
3260eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer        String temperatureString;
3270eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer
3280eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer        if (mTemperature < MIN_TEMPERATURE || mTemperature > MAX_TEMPERATURE) {
3290eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer            temperatureString = mInvalidTemperature;
3300eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer        } else {
3310eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer            temperatureString = String.valueOf(mTemperature);
3320eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer        }
3330eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer
3340eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer        mText.setText(getContext().getString(R.string.hvac_temperature_template,
3350eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer                temperatureString));
3360eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer        mFloatingText.setText(getContext()
3370eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer                .getString(R.string.hvac_temperature_template, temperatureString));
3380eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer
3390eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer        // Only animate the color if the button is currently enabled.
3400eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer        if (mIsOn) {
3410eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer            changeTemperatureColor(startColor, endColor);
3420eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer        }
3430eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer    }
3440eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer
3450eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer    /**
3460eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer     * Sets whether or not the temperature bar is on. If it is off, it should show "off" instead
3470eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer     * of the temperature.
3480eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer     */
3490eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer    public void setIsOn(boolean isOn) {
3500eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer        mIsOn = isOn;
3510eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer        GradientDrawable temperatureBall
3520eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer                = (GradientDrawable) mTemperatureBar.getBackground();
3530eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer        if (mIsOn) {
3540eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer            mFloatingText.setVisibility(VISIBLE);
3550eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer            mOffText.setVisibility(GONE);
3560eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer            temperatureBall.setColor(getTemperatureColor(mTemperature));
3570eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer            setAlpha(1.0f);
3580eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer        } else {
3590eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer            mOffText.setVisibility(VISIBLE);
3600eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer            mFloatingText.setVisibility(GONE);
3610eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer            temperatureBall.setColor(mOffColor);
3620eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer            setAlpha(.2f);
3630eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer        }
3640eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer    }
3650eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer
3660eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer    private int getTemperatureColor(int temperature) {
3670eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer        if (temperature >= 78) {
3680eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer            return mTempColor1;
3690eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer        } else if (temperature >= 74 && temperature < 78) {
3700eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer            return mTempColor2;
3710eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer        } else if (temperature >= 70 && temperature < 74) {
3720eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer            return mTempColor3;
3730eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer        } else if (temperature >= 66 && temperature < 70) {
3740eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer            return mTempColor4;
3750eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer        } else {
3760eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer            return mTempColor5;
3770eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer        }
3780eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer    }
3790eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer
3800eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer    private final ValueAnimator.AnimatorUpdateListener mTranslationYListener
3810eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer            = new ValueAnimator.AnimatorUpdateListener() {
3820eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer        @Override
3830eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer        public void onAnimationUpdate(ValueAnimator animation) {
3840eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer            float translation = (float) animation.getAnimatedValue();
3850eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer            mTemperatureBar.setTranslationY(translation);
3860eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer        }
3870eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer    };
3880eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer
3890eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer    private final ValueAnimator.AnimatorUpdateListener mWidthUpdateListener
3900eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer            = new ValueAnimator.AnimatorUpdateListener() {
3910eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer        @Override
3920eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer        public void onAnimationUpdate(ValueAnimator animation) {
3930eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer            int width = (Integer) animation.getAnimatedValue();
3940eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer            mTemperatureBar.getLayoutParams().width = width;
3950eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer            mTemperatureBar.requestLayout();
3960eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer        }
3970eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer    };
3980eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer
3990eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer    private final ValueAnimator.AnimatorUpdateListener mHeightUpdateListener
4000eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer            = new ValueAnimator.AnimatorUpdateListener() {
4010eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer        @Override
4020eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer        public void onAnimationUpdate(ValueAnimator animation) {
4030eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer            int height = (Integer) animation.getAnimatedValue();
4040eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer            int currentHeight = mTemperatureBar.getLayoutParams().height;
4050eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer            mTemperatureBar.getLayoutParams().height = height;
4060eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer            mTemperatureBar.setTop(mTemperatureBar.getTop() + height - currentHeight);
4070eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer            mTemperatureBar.requestLayout();
4080eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer        }
4090eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer    };
4100eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer
4110eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer    private final ValueAnimator.AnimatorUpdateListener mTemperatureColorListener
4120eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer            = new ValueAnimator.AnimatorUpdateListener() {
4130eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer        @Override
4140eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer        public void onAnimationUpdate(ValueAnimator animation) {
4150eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer            int color = (Integer) animation.getAnimatedValue();
4160eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer            ((GradientDrawable) mTemperatureBar.getBackground()).setColor(color);
4170eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer        }
4180eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer    };
4190eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer
4200eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer    private ObjectAnimator getAlphaAnimator(View view, boolean fade) {
4210eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer        return getAlphaAnimator(view, fade, EXPAND_ANIMATION_TIME_MS);
4220eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer    }
4230eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer
4240eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer    private ObjectAnimator getAlphaAnimator(View view, boolean fade, int duration) {
4250eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer
4260eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer        float startingAlpha = BUTTON_ALPHA_COLLAPSED;
4270eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer        float endingAlpha = BUTTON_ALPHA_EXPANDED;
4280eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer
4290eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer        if (fade) {
4300eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer            startingAlpha = BUTTON_ALPHA_EXPANDED;
4310eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer            endingAlpha = BUTTON_ALPHA_COLLAPSED;
4320eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer        }
4330eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer
4340eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer        return ObjectAnimator.ofFloat(view, View.ALPHA,
4350eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer                startingAlpha, endingAlpha).setDuration(duration);
4360eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer    }
4370eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer}
438