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