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