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