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