1/* 2 * Copyright (C) 2015 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 com.android.tv.ui; 18 19import android.animation.Animator; 20import android.animation.Animator.AnimatorListener; 21import android.animation.AnimatorInflater; 22import android.animation.AnimatorListenerAdapter; 23import android.content.Context; 24import android.text.TextUtils; 25import android.util.AttributeSet; 26import android.view.View; 27import android.widget.ImageView; 28import android.widget.ImageView.ScaleType; 29import android.widget.LinearLayout; 30import android.widget.TextView; 31 32import com.android.tv.R; 33import com.android.tv.ui.TunableTvView.BlockScreenType; 34 35public class BlockScreenView extends LinearLayout { 36 private View mContainerView; 37 private View mImageContainer; 38 private ImageView mNormalImageView; 39 private ImageView mShrunkenImageView; 40 private View mSpace; 41 private TextView mTextView; 42 43 private final int mSpacingNormal; 44 private final int mSpacingShrunken; 45 46 // Animators used for fade in/out of block screen icon. 47 private Animator mFadeIn; 48 private Animator mFadeOut; 49 50 public BlockScreenView(Context context) { 51 this(context, null, 0); 52 } 53 54 public BlockScreenView(Context context, AttributeSet attrs) { 55 this(context, attrs, 0); 56 } 57 58 public BlockScreenView(Context context, AttributeSet attrs, int defStyle) { 59 super(context, attrs, defStyle); 60 mSpacingNormal = getResources().getDimensionPixelOffset( 61 R.dimen.tvview_block_vertical_spacing); 62 mSpacingShrunken = getResources().getDimensionPixelOffset( 63 R.dimen.shrunken_tvview_block_vertical_spacing); 64 } 65 66 @Override 67 protected void onFinishInflate() { 68 super.onFinishInflate(); 69 mContainerView = findViewById(R.id.block_screen_container); 70 mImageContainer = findViewById(R.id.image_container); 71 mNormalImageView = (ImageView) findViewById(R.id.block_screen_icon); 72 mShrunkenImageView = (ImageView) findViewById(R.id.block_screen_shrunken_icon); 73 mSpace = findViewById(R.id.space); 74 mTextView = (TextView) findViewById(R.id.block_screen_text); 75 mFadeIn = AnimatorInflater.loadAnimator(getContext(), 76 R.animator.tvview_block_screen_fade_in); 77 mFadeIn.setTarget(mContainerView); 78 mFadeOut = AnimatorInflater.loadAnimator(getContext(), 79 R.animator.tvview_block_screen_fade_out); 80 mFadeOut.setTarget(mContainerView); 81 mFadeOut.addListener(new AnimatorListenerAdapter() { 82 @Override 83 public void onAnimationEnd(Animator animation) { 84 mContainerView.setVisibility(GONE); 85 mContainerView.setAlpha(1f); 86 } 87 }); 88 } 89 90 /** 91 * Sets the normal image. 92 */ 93 public void setImage(int resId) { 94 mNormalImageView.setImageResource(resId); 95 updateSpaceVisibility(); 96 } 97 98 /** 99 * Sets the scale type of the normal image. 100 */ 101 public void setScaleType(ScaleType scaleType) { 102 mNormalImageView.setScaleType(scaleType); 103 updateSpaceVisibility(); 104 } 105 106 /** 107 * Sets the shrunken image. 108 */ 109 public void setShrunkenImage(int resId) { 110 mShrunkenImageView.setImageResource(resId); 111 updateSpaceVisibility(); 112 } 113 114 /** 115 * Show or hide the image of this view. 116 */ 117 public void setImageVisibility(boolean visible) { 118 mImageContainer.setVisibility(visible ? VISIBLE : GONE); 119 updateSpaceVisibility(); 120 } 121 122 /** 123 * Sets the text message. 124 */ 125 public void setText(int resId) { 126 mTextView.setText(resId); 127 updateSpaceVisibility(); 128 } 129 130 /** 131 * Sets the text message. 132 */ 133 public void setText(String text) { 134 mTextView.setText(text); 135 updateSpaceVisibility(); 136 } 137 138 private void updateSpaceVisibility() { 139 if (isImageViewVisible() && isTextViewVisible(mTextView)) { 140 mSpace.setVisibility(VISIBLE); 141 } else { 142 mSpace.setVisibility(GONE); 143 } 144 } 145 146 private boolean isImageViewVisible() { 147 return mImageContainer.getVisibility() == VISIBLE 148 && (isImageViewVisible(mNormalImageView) || isImageViewVisible(mShrunkenImageView)); 149 } 150 151 private static boolean isImageViewVisible(ImageView imageView) { 152 return imageView.getVisibility() != GONE && imageView.getDrawable() != null; 153 } 154 155 private static boolean isTextViewVisible(TextView textView) { 156 return textView.getVisibility() != GONE && !TextUtils.isEmpty(textView.getText()); 157 } 158 159 /** 160 * Changes the spacing between the image view and the text view according to the 161 * {@code blockScreenType}. 162 */ 163 public void setSpacing(@BlockScreenType int blockScreenType) { 164 mSpace.getLayoutParams().height = 165 blockScreenType == TunableTvView.BLOCK_SCREEN_TYPE_SHRUNKEN_TV_VIEW 166 ? mSpacingShrunken : mSpacingNormal; 167 requestLayout(); 168 } 169 170 /** 171 * Changes the view layout according to the {@code blockScreenType}. 172 */ 173 public void onBlockStatusChanged(@BlockScreenType int blockScreenType, boolean withAnimation) { 174 if (!withAnimation) { 175 switch (blockScreenType) { 176 case TunableTvView.BLOCK_SCREEN_TYPE_NO_UI: 177 mContainerView.setVisibility(GONE); 178 break; 179 case TunableTvView.BLOCK_SCREEN_TYPE_SHRUNKEN_TV_VIEW: 180 mNormalImageView.setVisibility(GONE); 181 mShrunkenImageView.setVisibility(VISIBLE); 182 mContainerView.setVisibility(VISIBLE); 183 break; 184 case TunableTvView.BLOCK_SCREEN_TYPE_NORMAL: 185 mNormalImageView.setVisibility(VISIBLE); 186 mShrunkenImageView.setVisibility(GONE); 187 mContainerView.setVisibility(VISIBLE); 188 break; 189 } 190 } else { 191 switch (blockScreenType) { 192 case TunableTvView.BLOCK_SCREEN_TYPE_NO_UI: 193 if (mContainerView.getVisibility() == VISIBLE) { 194 mFadeOut.start(); 195 } 196 break; 197 case TunableTvView.BLOCK_SCREEN_TYPE_SHRUNKEN_TV_VIEW: 198 mNormalImageView.setVisibility(GONE); 199 mShrunkenImageView.setVisibility(VISIBLE); 200 mContainerView.setVisibility(VISIBLE); 201 if (mContainerView.getVisibility() == GONE) { 202 mFadeIn.start(); 203 } 204 break; 205 case TunableTvView.BLOCK_SCREEN_TYPE_NORMAL: 206 mNormalImageView.setVisibility(VISIBLE); 207 mShrunkenImageView.setVisibility(GONE); 208 mContainerView.setVisibility(VISIBLE); 209 if (mContainerView.getVisibility() == GONE) { 210 mFadeIn.start(); 211 } 212 break; 213 } 214 } 215 updateSpaceVisibility(); 216 } 217 218 /** 219 * Scales the contents view by the given {@code scale}. 220 */ 221 public void scaleContainerView(float scale) { 222 mContainerView.setScaleX(scale); 223 mContainerView.setScaleY(scale); 224 } 225 226 public void addFadeOutAnimationListener(AnimatorListener listener) { 227 mFadeOut.addListener(listener); 228 } 229 230 /** 231 * Ends the currently running animations. 232 */ 233 public void endAnimations() { 234 if (mFadeIn != null && mFadeIn.isRunning()) { 235 mFadeIn.end(); 236 } 237 if (mFadeOut != null && mFadeOut.isRunning()) { 238 mFadeOut.end(); 239 } 240 } 241} 242