SpeechOrbView.java revision a9b678302ddee2149e5605afd429c74ba5625c24
1package android.support.v17.leanback.widget;
2
3import android.content.Context;
4import android.content.res.Resources;
5import android.graphics.Rect;
6import android.graphics.drawable.GradientDrawable;
7import android.support.v17.leanback.R;
8import android.util.AttributeSet;
9import android.view.LayoutInflater;
10import android.view.View;
11import android.widget.FrameLayout;
12import android.widget.ImageView;
13
14public class SpeechOrbView extends FrameLayout implements View.OnClickListener {
15    private OnClickListener mListener;
16    private View mSpeechOrbView;
17    private final float mFocusedZoom;
18    private final float mSoundLevelMaxZoom;
19    private final int mNotRecordingColor;
20    private final int mRecordingColor;
21    private ImageView mIcon;
22
23    private int mCurrentLevel = 0;
24    private boolean mListening = false;
25
26    public SpeechOrbView(Context context) {
27        this(context, null);
28    }
29
30    public SpeechOrbView(Context context, AttributeSet attrs) {
31        this(context, attrs, 0);
32    }
33
34    public SpeechOrbView(Context context, AttributeSet attrs, int defStyle) {
35        super(context, attrs, defStyle);
36
37        LayoutInflater inflater = (LayoutInflater) context
38                .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
39        View root = inflater.inflate(R.layout.lb_speech_orb, this, true);
40        mSpeechOrbView = root.findViewById(R.id.lb_speech_orb);
41        mIcon = (ImageView)root.findViewById(R.id.lb_speech_icon);
42
43        setFocusable(true);
44        setClipChildren(false);
45
46        Resources resources = context.getResources();
47        mFocusedZoom =
48                resources.getFraction(R.fraction.lb_search_bar_speech_orb_focused_zoom, 1, 1);
49        mSoundLevelMaxZoom =
50                resources.getFraction(R.fraction.lb_search_bar_speech_orb_max_level_zoom, 1, 1);
51        mNotRecordingColor = resources.getColor(R.color.lb_speech_orb_not_recording);
52        mRecordingColor = resources.getColor(R.color.lb_speech_orb_recording);
53
54        setOnClickListener(this);
55        showNotListening();
56    }
57
58    @Override
59    public void onClick(View view) {
60        if (null != mListener) {
61            mListener.onClick(view);
62        }
63    }
64
65    @Override
66    protected void onFocusChanged(boolean gainFocus, int direction, Rect previouslyFocusedRect) {
67        super.onFocusChanged(gainFocus, direction, previouslyFocusedRect);
68        final float zoom = gainFocus ? mFocusedZoom : 1f;
69        mSpeechOrbView.animate().scaleX(zoom).scaleY(zoom).setDuration(200).start();
70        if (gainFocus) {
71            mIcon.setImageResource(R.drawable.lb_search_mic);
72        } else {
73            mIcon.setImageResource(R.drawable.lb_search_mic_out);
74        }
75    }
76
77    /**
78     * Set the on click listener for the orb
79     * @param listener The listener.
80     */
81    public void setOnOrbClickedListener(OnClickListener listener) {
82        mListener = listener;
83    }
84
85    public void showListening() {
86        setOrbColor(mRecordingColor);
87        mSpeechOrbView.setScaleX(1f);
88        mSpeechOrbView.setScaleY(1f);
89        mListening = true;
90    }
91
92    public void showNotListening() {
93        setOrbColor(mNotRecordingColor);
94        mSpeechOrbView.setScaleX(1f);
95        mSpeechOrbView.setScaleY(1f);
96        mListening = false;
97    }
98
99    public void setSoundLevel(int level) {
100        if (!mListening) return;
101
102        // Either ease towards the target level, or decay away from it depending on whether
103        // its higher or lower than the current.
104        if (level > mCurrentLevel) {
105            mCurrentLevel = mCurrentLevel + ((level - mCurrentLevel) / 4);
106        } else {
107            mCurrentLevel = (int) (mCurrentLevel * 0.95f);
108        }
109
110        float zoom = mFocusedZoom + ((mSoundLevelMaxZoom - mFocusedZoom) * mCurrentLevel) / 100;
111        mSpeechOrbView.setScaleX(zoom);
112        mSpeechOrbView.setScaleY(zoom);
113    }
114
115    public void setOrbColor(int color) {
116        if (mSpeechOrbView.getBackground() instanceof GradientDrawable) {
117            ((GradientDrawable) mSpeechOrbView.getBackground()).setColor(color);
118        }
119    }
120
121}
122