1/*
2 * Copyright (C) 2016 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
5 * in compliance with the License. You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software distributed under the License
10 * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
11 * or implied. See the License for the specific language governing permissions and limitations under
12 * the License.
13 */
14package android.support.v17.leanback.widget;
15
16import static android.support.annotation.RestrictTo.Scope.LIBRARY_GROUP;
17
18import android.animation.Animator;
19import android.animation.ObjectAnimator;
20import android.animation.ValueAnimator;
21import android.content.Context;
22import android.support.annotation.RestrictTo;
23import android.support.v17.leanback.R;
24import android.util.AttributeSet;
25import android.view.LayoutInflater;
26import android.view.View;
27import android.view.animation.LinearInterpolator;
28import android.widget.ImageView;
29import android.widget.LinearLayout;
30
31/**
32 * The view displaying 3 animated peak meters next to each other when a media item is playing.
33 * @hide
34 */
35@RestrictTo(LIBRARY_GROUP)
36public class MediaNowPlayingView extends LinearLayout{
37
38    private final ImageView mImage1;
39    private final ImageView mImage2;
40    private final ImageView mImage3;
41    private final ObjectAnimator mObjectAnimator1;
42    private final ObjectAnimator mObjectAnimator2;
43    private final ObjectAnimator mObjectAnimator3;
44    protected final LinearInterpolator mLinearInterpolator = new LinearInterpolator();
45
46    public MediaNowPlayingView(Context context, AttributeSet attrs) {
47        super(context, attrs);
48
49        LayoutInflater.from(context).inflate(R.layout.lb_playback_now_playing_bars, this, true);
50        mImage1 = findViewById(R.id.bar1);
51        mImage2 = findViewById(R.id.bar2);
52        mImage3 = findViewById(R.id.bar3);
53
54        mImage1.setPivotY(mImage1.getDrawable().getIntrinsicHeight());
55        mImage2.setPivotY(mImage2.getDrawable().getIntrinsicHeight());
56        mImage3.setPivotY(mImage3.getDrawable().getIntrinsicHeight());
57
58        setDropScale(mImage1);
59        setDropScale(mImage2);
60        setDropScale(mImage3);
61
62        mObjectAnimator1 = ObjectAnimator.ofFloat(mImage1, "scaleY", 5f / 12f, 3f / 12f, 5f / 12f,
63                7f / 12f, 9f / 12f, 10f / 12f, 11f / 12f, 12f / 12f, 11f / 12f, 12f / 12f,
64                10f / 12f, 8f / 12f, 6f / 12f, 4f / 12f, 2f / 12f, 4f / 12f, 6f / 12f, 7f / 12f,
65                9f / 12f, 11f / 12f, 9f / 12f, 7f / 12f, 5f / 12f, 3f / 12f, 5f / 12f, 8f / 12f,
66                5f / 12f, 3f / 12f, 4f / 12f, 5f / 12f);
67        mObjectAnimator1.setRepeatCount(ValueAnimator.INFINITE);
68        mObjectAnimator1.setDuration(2320);
69        mObjectAnimator1.setInterpolator(mLinearInterpolator);
70
71        mObjectAnimator2 = ObjectAnimator.ofFloat(mImage2, "scaleY", 12f / 12f, 11f / 12f,
72                10f / 12f, 11f / 12f, 12f / 12f, 11f / 12f, 9f / 12f, 7f / 12f, 9f / 12f, 11f / 12f,
73                12f / 12f, 10f / 12f, 8f / 12f, 10f / 12f, 12f / 12f, 11f / 12f, 9f / 12f, 5f / 12f,
74                3f / 12f, 5f / 12f, 8f / 12f, 10f / 12f, 12f / 12f, 10f / 12f, 9f / 12f, 8f / 12f,
75                12f / 12f);
76        mObjectAnimator2.setRepeatCount(ValueAnimator.INFINITE);
77        mObjectAnimator2.setDuration(2080);
78        mObjectAnimator2.setInterpolator(mLinearInterpolator);
79
80        mObjectAnimator3 = ObjectAnimator.ofFloat(mImage3, "scaleY", 8f / 12f, 9f / 12f, 10f / 12f,
81                12f / 12f, 11f / 12f, 9f / 12f, 7f / 12f, 5f / 12f, 7f / 12f, 8f / 12f, 9f / 12f,
82                12f / 12f, 11f / 12f, 12f / 12f, 9f / 12f, 7f / 12f, 9f / 12f, 11f / 12f, 12f / 12f,
83                10f / 12f, 8f / 12f, 9f / 12f, 7f / 12f, 5f / 12f, 3f / 12f, 8f / 12f);
84        mObjectAnimator3.setRepeatCount(ValueAnimator.INFINITE);
85        mObjectAnimator3.setDuration(2000);
86        mObjectAnimator3.setInterpolator(mLinearInterpolator);
87    }
88
89    static void setDropScale(View view) {
90        view.setScaleY(1f / 12f);
91    }
92
93    @Override
94    public void setVisibility(int visibility) {
95        super.setVisibility(visibility);
96        if (visibility == View.GONE) {
97            stopAnimation();
98        } else {
99            startAnimation();
100        }
101    }
102
103    @Override
104    protected void onAttachedToWindow() {
105        super.onAttachedToWindow();
106        if (getVisibility() == View.VISIBLE)
107            startAnimation();
108    }
109
110    @Override
111    protected void onDetachedFromWindow() {
112        super.onDetachedFromWindow();
113        stopAnimation();
114    }
115
116    private void startAnimation() {
117        startAnimation(mObjectAnimator1);
118        startAnimation(mObjectAnimator2);
119        startAnimation(mObjectAnimator3);
120        mImage1.setVisibility(View.VISIBLE);
121        mImage2.setVisibility(View.VISIBLE);
122        mImage3.setVisibility(View.VISIBLE);
123    }
124
125    private void stopAnimation() {
126        stopAnimation(mObjectAnimator1, mImage1);
127        stopAnimation(mObjectAnimator2, mImage2);
128        stopAnimation(mObjectAnimator3, mImage3);
129        mImage1.setVisibility(View.GONE);
130        mImage2.setVisibility(View.GONE);
131        mImage3.setVisibility(View.GONE);
132    }
133
134    private void startAnimation(Animator animator) {
135        if (!animator.isStarted()) {
136            animator.start();
137        }
138    }
139
140    private void stopAnimation(Animator animator, View view) {
141        if (animator.isStarted()) {
142            animator.cancel();
143            setDropScale(view);
144        }
145    }
146}
147