1package android.support.v17.leanback.widget; 2 3import android.content.Context; 4import android.content.res.Resources; 5import android.graphics.Color; 6import android.support.v17.leanback.R; 7import android.util.AttributeSet; 8 9public class SpeechOrbView extends SearchOrbView { 10 private final float mSoundLevelMaxZoom; 11 private final Colors mListeningOrbColors; 12 private final Colors mNotListeningOrbColors; 13 14 private int mCurrentLevel = 0; 15 private boolean mListening = false; 16 17 public SpeechOrbView(Context context) { 18 this(context, null); 19 } 20 21 public SpeechOrbView(Context context, AttributeSet attrs) { 22 this(context, attrs, 0); 23 } 24 25 public SpeechOrbView(Context context, AttributeSet attrs, int defStyle) { 26 super(context, attrs, defStyle); 27 28 Resources resources = context.getResources(); 29 mSoundLevelMaxZoom = 30 resources.getFraction(R.fraction.lb_search_bar_speech_orb_max_level_zoom, 1, 1); 31 32 mNotListeningOrbColors = new Colors(resources.getColor(R.color.lb_speech_orb_not_recording), 33 resources.getColor(R.color.lb_speech_orb_not_recording_pulsed), 34 resources.getColor(R.color.lb_speech_orb_not_recording_icon)); 35 mListeningOrbColors = new Colors(resources.getColor(R.color.lb_speech_orb_recording), 36 resources.getColor(R.color.lb_speech_orb_recording), 37 Color.TRANSPARENT); 38 39 showNotListening(); 40 } 41 42 @Override 43 int getLayoutResourceId() { 44 return R.layout.lb_speech_orb; 45 } 46 47 public void showListening() { 48 setOrbColors(mListeningOrbColors); 49 setOrbIcon(getResources().getDrawable(R.drawable.lb_ic_search_mic)); 50 // Assume focused 51 animateOnFocus(true); 52 enableOrbColorAnimation(false); 53 scaleOrbViewOnly(1f); 54 mCurrentLevel = 0; 55 mListening = true; 56 } 57 58 public void showNotListening() { 59 setOrbColors(mNotListeningOrbColors); 60 setOrbIcon(getResources().getDrawable(R.drawable.lb_ic_search_mic_out)); 61 animateOnFocus(hasFocus()); 62 scaleOrbViewOnly(1f); 63 mListening = false; 64 } 65 66 public void setSoundLevel(int level) { 67 if (!mListening) return; 68 69 // Either ease towards the target level, or decay away from it depending on whether 70 // its higher or lower than the current. 71 if (level > mCurrentLevel) { 72 mCurrentLevel = mCurrentLevel + ((level - mCurrentLevel) / 2); 73 } else { 74 mCurrentLevel = (int) (mCurrentLevel * 0.7f); 75 } 76 77 float zoom = 1f + (mSoundLevelMaxZoom - getFocusedZoom()) * mCurrentLevel / 100; 78 79 scaleOrbViewOnly(zoom); 80 } 81} 82