SearchOrbView.java revision aadb8928f5920c758c1a385bbc8b8b128a60657c
1/* 2 * Copyright (C) 2014 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17package android.support.v17.leanback.widget; 18 19import android.animation.ArgbEvaluator; 20import android.animation.ValueAnimator; 21import android.content.Context; 22import android.graphics.Color; 23import android.graphics.Rect; 24import android.graphics.drawable.GradientDrawable; 25import android.support.v17.leanback.R; 26import android.util.AttributeSet; 27import android.view.LayoutInflater; 28import android.view.View; 29import android.widget.FrameLayout; 30 31public class SearchOrbView extends FrameLayout implements View.OnClickListener { 32 private OnClickListener mListener; 33 private View mSearchOrbView; 34 private int mSearchOrbColor, mSearchOrbColorBright; 35 private final float mFocusedZoom; 36 private final float mBrightnessAlpha; 37 private final int mPulseDurationMs; 38 private final int mScaleDownDurationMs; 39 private ValueAnimator mColorAnimator; 40 41 private final ArgbEvaluator mColorEvaluator = new ArgbEvaluator(); 42 43 private final ValueAnimator.AnimatorUpdateListener mUpdateListener = 44 new ValueAnimator.AnimatorUpdateListener() { 45 @Override 46 public void onAnimationUpdate(ValueAnimator animator) { 47 Integer color = (Integer) animator.getAnimatedValue(); 48 setOrbViewColor(color.intValue()); 49 } 50 }; 51 52 public SearchOrbView(Context context) { 53 this(context, null); 54 } 55 56 public SearchOrbView(Context context, AttributeSet attrs) { 57 this(context, attrs, 0); 58 } 59 60 public SearchOrbView(Context context, AttributeSet attrs, int defStyle) { 61 super(context, attrs, defStyle); 62 63 LayoutInflater inflater = (LayoutInflater) context 64 .getSystemService(Context.LAYOUT_INFLATER_SERVICE); 65 View root = inflater.inflate(R.layout.lb_search_orb, this, true); 66 mSearchOrbView = root.findViewById(R.id.search_orb); 67 68 // By default we are not visible 69 setVisibility(INVISIBLE); 70 setFocusable(true); 71 setClipChildren(false); 72 73 mFocusedZoom = context.getResources().getFraction( 74 R.fraction.lb_search_orb_focused_zoom, 1, 1); 75 mBrightnessAlpha = context.getResources().getFraction( 76 R.fraction.lb_search_orb_brightness_alpha, 1, 1); 77 mPulseDurationMs = context.getResources().getInteger( 78 R.integer.lb_search_orb_pulse_duration_ms); 79 mScaleDownDurationMs = context.getResources().getInteger( 80 R.integer.lb_search_orb_scale_down_duration_ms); 81 82 setOnClickListener(this); 83 } 84 85 @Override 86 public void onClick(View view) { 87 if (null != mListener) { 88 mListener.onClick(view); 89 } 90 } 91 92 @Override 93 protected void onFocusChanged(boolean gainFocus, int direction, Rect previouslyFocusedRect) { 94 super.onFocusChanged(gainFocus, direction, previouslyFocusedRect); 95 final float zoom = gainFocus ? mFocusedZoom : 1f; 96 final int duration = gainFocus ? mPulseDurationMs : mScaleDownDurationMs; 97 mSearchOrbView.animate().scaleX(zoom).scaleY(zoom).setDuration(duration).start(); 98 enableOrbColorAnimation(gainFocus); 99 } 100 101 private void enableOrbColorAnimation(boolean enable) { 102 if (mColorAnimator != null) { 103 mColorAnimator.end(); 104 mColorAnimator = null; 105 } 106 if (enable) { 107 // TODO: set interpolator (quantum if available) 108 mColorAnimator = ValueAnimator.ofObject(mColorEvaluator, 109 mSearchOrbColor, mSearchOrbColorBright, mSearchOrbColor); 110 mColorAnimator.setRepeatCount(ValueAnimator.INFINITE); 111 mColorAnimator.setDuration(mPulseDurationMs * 2); 112 mColorAnimator.addUpdateListener(mUpdateListener); 113 mColorAnimator.start(); 114 } 115 } 116 117 private void setOrbViewColor(int color) { 118 if (mSearchOrbView.getBackground() instanceof GradientDrawable) { 119 ((GradientDrawable) mSearchOrbView.getBackground()).setColor(color); 120 } 121 } 122 123 /** 124 * Set the on click listener for the orb 125 * @param listener The listener. 126 */ 127 public void setOnOrbClickedListener(OnClickListener listener) { 128 mListener = listener; 129 if (null != listener) { 130 setVisibility(View.VISIBLE); 131 } else { 132 setVisibility(View.INVISIBLE); 133 } 134 } 135 136 private int getBrightColor(int color) { 137 final float brightnessValue = 0xff * mBrightnessAlpha; 138 int red = (int)(Color.red(color) * (1 - mBrightnessAlpha) + brightnessValue); 139 int green = (int)(Color.green(color) * (1 - mBrightnessAlpha) + brightnessValue); 140 int blue = (int)(Color.blue(color) * (1 - mBrightnessAlpha) + brightnessValue); 141 int alpha = (int)(Color.alpha(color) * (1 - mBrightnessAlpha) + brightnessValue); 142 return Color.argb(alpha, red, green, blue); 143 } 144 145 public void setOrbColor(int color) { 146 mSearchOrbColor = color; 147 mSearchOrbColorBright = getBrightColor(color); 148 149 if (mColorAnimator == null) { 150 setOrbViewColor(color); 151 } else { 152 enableOrbColorAnimation(true); 153 } 154 } 155} 156