Home | History | Annotate | Download | only in app
      1 /*
      2  * Copyright (C) 2014 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
      5  * in compliance with the License. You may obtain a copy of the License at
      6  *
      7  * http://www.apache.org/licenses/LICENSE-2.0
      8  *
      9  * Unless required by applicable law or agreed to in writing, software distributed under the License
     10  * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
     11  * or implied. See the License for the specific language governing permissions and limitations under
     12  * the License.
     13  */
     14 package android.support.v17.leanback.app;
     15 
     16 import android.graphics.Paint;
     17 import android.graphics.Paint.FontMetricsInt;
     18 import android.graphics.PixelFormat;
     19 import android.graphics.drawable.Drawable;
     20 import android.os.Bundle;
     21 import android.support.v17.leanback.R;
     22 import android.text.TextUtils;
     23 import android.view.LayoutInflater;
     24 import android.view.View;
     25 import android.view.ViewGroup;
     26 import android.widget.Button;
     27 import android.widget.ImageView;
     28 import android.widget.TextView;
     29 
     30 /**
     31  * A fragment for displaying an error indication.
     32  */
     33 public class ErrorFragment extends BrandedFragment {
     34 
     35     private ViewGroup mErrorFrame;
     36     private ImageView mImageView;
     37     private TextView mTextView;
     38     private Button mButton;
     39     private Drawable mDrawable;
     40     private CharSequence mMessage;
     41     private String mButtonText;
     42     private View.OnClickListener mButtonClickListener;
     43     private Drawable mBackgroundDrawable;
     44     private boolean mIsBackgroundTranslucent = true;
     45 
     46     /**
     47      * Sets the default background.
     48      *
     49      * @param translucent True to set a translucent background.
     50      */
     51     public void setDefaultBackground(boolean translucent) {
     52         mBackgroundDrawable = null;
     53         mIsBackgroundTranslucent = translucent;
     54         updateBackground();
     55         updateMessage();
     56     }
     57 
     58     /**
     59      * Returns true if the background is translucent.
     60      */
     61     public boolean isBackgroundTranslucent() {
     62         return mIsBackgroundTranslucent;
     63     }
     64 
     65     /**
     66      * Sets a drawable for the fragment background.
     67      *
     68      * @param drawable The drawable used for the background.
     69      */
     70     public void setBackgroundDrawable(Drawable drawable) {
     71         mBackgroundDrawable = drawable;
     72         if (drawable != null) {
     73             final int opacity = drawable.getOpacity();
     74             mIsBackgroundTranslucent = (opacity == PixelFormat.TRANSLUCENT
     75                     || opacity == PixelFormat.TRANSPARENT);
     76         }
     77         updateBackground();
     78         updateMessage();
     79     }
     80 
     81     /**
     82      * Returns the background drawable.  May be null if a default is used.
     83      */
     84     public Drawable getBackgroundDrawable() {
     85         return mBackgroundDrawable;
     86     }
     87 
     88     /**
     89      * Sets the drawable to be used for the error image.
     90      *
     91      * @param drawable The drawable used for the error image.
     92      */
     93     public void setImageDrawable(Drawable drawable) {
     94         mDrawable = drawable;
     95         updateImageDrawable();
     96     }
     97 
     98     /**
     99      * Returns the drawable used for the error image.
    100      */
    101     public Drawable getImageDrawable() {
    102         return mDrawable;
    103     }
    104 
    105     /**
    106      * Sets the error message.
    107      *
    108      * @param message The error message.
    109      */
    110     public void setMessage(CharSequence message) {
    111         mMessage = message;
    112         updateMessage();
    113     }
    114 
    115     /**
    116      * Returns the error message.
    117      */
    118     public CharSequence getMessage() {
    119         return mMessage;
    120     }
    121 
    122     /**
    123      * Sets the button text.
    124      *
    125      * @param text The button text.
    126      */
    127     public void setButtonText(String text) {
    128         mButtonText = text;
    129         updateButton();
    130     }
    131 
    132     /**
    133      * Returns the button text.
    134      */
    135     public String getButtonText() {
    136         return mButtonText;
    137     }
    138 
    139     /**
    140      * Set the button click listener.
    141      *
    142      * @param clickListener The click listener for the button.
    143      */
    144     public void setButtonClickListener(View.OnClickListener clickListener) {
    145         mButtonClickListener = clickListener;
    146         updateButton();
    147     }
    148 
    149     /**
    150      * Returns the button click listener.
    151      */
    152     public View.OnClickListener getButtonClickListener() {
    153         return mButtonClickListener;
    154     }
    155 
    156     @Override
    157     public View onCreateView(LayoutInflater inflater, ViewGroup container,
    158             Bundle savedInstanceState) {
    159         View root = inflater.inflate(R.layout.lb_error_fragment, container, false);
    160 
    161         mErrorFrame = (ViewGroup) root.findViewById(R.id.error_frame);
    162         updateBackground();
    163 
    164         installTitleView(inflater, mErrorFrame, savedInstanceState);
    165 
    166         mImageView = (ImageView) root.findViewById(R.id.image);
    167         updateImageDrawable();
    168 
    169         mTextView = (TextView) root.findViewById(R.id.message);
    170         updateMessage();
    171 
    172         mButton = (Button) root.findViewById(R.id.button);
    173         updateButton();
    174 
    175         FontMetricsInt metrics = getFontMetricsInt(mTextView);
    176         int underImageBaselineMargin = container.getResources().getDimensionPixelSize(
    177                 R.dimen.lb_error_under_image_baseline_margin);
    178         setTopMargin(mTextView, underImageBaselineMargin + metrics.ascent);
    179 
    180         int underMessageBaselineMargin = container.getResources().getDimensionPixelSize(
    181                 R.dimen.lb_error_under_message_baseline_margin);
    182         setTopMargin(mButton, underMessageBaselineMargin - metrics.descent);
    183 
    184         return root;
    185     }
    186 
    187     private void updateBackground() {
    188         if (mErrorFrame != null) {
    189             if (mBackgroundDrawable != null) {
    190                 mErrorFrame.setBackground(mBackgroundDrawable);
    191             } else {
    192                 mErrorFrame.setBackgroundColor(mErrorFrame.getResources().getColor(
    193                         mIsBackgroundTranslucent
    194                                 ? R.color.lb_error_background_color_translucent
    195                                 : R.color.lb_error_background_color_opaque));
    196             }
    197         }
    198     }
    199 
    200     private void updateMessage() {
    201         if (mTextView != null) {
    202             mTextView.setText(mMessage);
    203             mTextView.setVisibility(TextUtils.isEmpty(mMessage) ? View.GONE : View.VISIBLE);
    204         }
    205     }
    206 
    207     private void updateImageDrawable() {
    208         if (mImageView != null) {
    209             mImageView.setImageDrawable(mDrawable);
    210             mImageView.setVisibility(mDrawable == null ? View.GONE : View.VISIBLE);
    211         }
    212     }
    213 
    214     private void updateButton() {
    215         if (mButton != null) {
    216             mButton.setText(mButtonText);
    217             mButton.setOnClickListener(mButtonClickListener);
    218             mButton.setVisibility(TextUtils.isEmpty(mButtonText) ? View.GONE : View.VISIBLE);
    219             mButton.requestFocus();
    220         }
    221     }
    222 
    223     @Override
    224     public void onStart() {
    225         super.onStart();
    226         mErrorFrame.requestFocus();
    227     }
    228 
    229     private static FontMetricsInt getFontMetricsInt(TextView textView) {
    230         Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);
    231         paint.setTextSize(textView.getTextSize());
    232         paint.setTypeface(textView.getTypeface());
    233         return paint.getFontMetricsInt();
    234     }
    235 
    236     private static void setTopMargin(TextView textView, int topMargin) {
    237         ViewGroup.MarginLayoutParams lp = (ViewGroup.MarginLayoutParams) textView.getLayoutParams();
    238         lp.topMargin = topMargin;
    239         textView.setLayoutParams(lp);
    240     }
    241 
    242 }
    243