ErrorSupportFragment.java revision 61905b0b52c50018dcaebcd79699c39b8f28d622
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 */ 14package android.support.v17.leanback.app; 15 16import android.os.Bundle; 17import android.support.v17.leanback.R; 18import android.support.v17.leanback.widget.TitleView; 19import android.text.TextUtils; 20import android.util.Log; 21import android.support.v4.app.Fragment; 22import android.view.LayoutInflater; 23import android.view.View; 24import android.view.View.OnClickListener; 25import android.view.ViewGroup; 26import android.widget.Button; 27import android.widget.ImageView; 28import android.widget.TextView; 29import android.graphics.Paint; 30import android.graphics.PixelFormat; 31import android.graphics.Paint.FontMetricsInt; 32import android.graphics.drawable.Drawable; 33 34/** 35 * A fragment for displaying an error indication. 36 */ 37public class ErrorSupportFragment extends Fragment { 38 39 private View mErrorFrame; 40 private String mTitle; 41 private Drawable mBadgeDrawable; 42 private TitleView mTitleView; 43 private ImageView mImageView; 44 private TextView mTextView; 45 private Button mButton; 46 private Drawable mDrawable; 47 private CharSequence mMessage; 48 private String mButtonText; 49 private View.OnClickListener mButtonClickListener; 50 private Drawable mBackgroundDrawable; 51 private boolean mIsBackgroundTranslucent = true; 52 53 /** 54 * Sets the drawable displayed in the browse fragment title. 55 * 56 * @param drawable The drawable to display in the browse fragment title. 57 */ 58 public void setBadgeDrawable(Drawable drawable) { 59 mBadgeDrawable = drawable; 60 updateTitle(); 61 } 62 63 /** 64 * Returns the badge drawable used in the fragment title. 65 */ 66 public Drawable getBadgeDrawable() { 67 return mBadgeDrawable; 68 } 69 70 /** 71 * Sets a title for the browse fragment. 72 * 73 * @param title The title of the browse fragment. 74 */ 75 public void setTitle(String title) { 76 mTitle = title; 77 updateTitle(); 78 } 79 80 /** 81 * Returns the title for the browse fragment. 82 */ 83 public String getTitle() { 84 return mTitle; 85 } 86 87 /** 88 * Sets the default background. 89 * 90 * @param translucent True to set a translucent background. 91 */ 92 public void setDefaultBackground(boolean translucent) { 93 mBackgroundDrawable = null; 94 mIsBackgroundTranslucent = translucent; 95 updateBackground(); 96 updateMessage(); 97 } 98 99 /** 100 * Returns true if the background is translucent. 101 */ 102 public boolean isBackgroundTranslucent() { 103 return mIsBackgroundTranslucent; 104 } 105 106 /** 107 * Sets a drawable for the fragment background. 108 * 109 * @param drawable The drawable used for the background. 110 */ 111 public void setBackgroundDrawable(Drawable drawable) { 112 mBackgroundDrawable = drawable; 113 if (drawable != null) { 114 final int opacity = drawable.getOpacity(); 115 mIsBackgroundTranslucent = (opacity == PixelFormat.TRANSLUCENT || 116 opacity == PixelFormat.TRANSPARENT); 117 } 118 updateBackground(); 119 updateMessage(); 120 } 121 122 /** 123 * Returns the background drawable. May be null if a default is used. 124 */ 125 public Drawable getBackgroundDrawable() { 126 return mBackgroundDrawable; 127 } 128 129 /** 130 * Sets the drawable to be used for the error image. 131 * 132 * @param drawable The drawable used for the error image. 133 */ 134 public void setImageDrawable(Drawable drawable) { 135 mDrawable = drawable; 136 updateImageDrawable(); 137 } 138 139 /** 140 * Returns the drawable used for the error image. 141 */ 142 public Drawable getImageDrawable() { 143 return mDrawable; 144 } 145 146 /** 147 * Sets the error message. 148 * 149 * @param message The error message. 150 */ 151 public void setMessage(CharSequence message) { 152 mMessage = message; 153 updateMessage(); 154 } 155 156 /** 157 * Returns the error message. 158 */ 159 public CharSequence getMessage() { 160 return mMessage; 161 } 162 163 /** 164 * Sets the button text. 165 * 166 * @param text The button text. 167 */ 168 public void setButtonText(String text) { 169 mButtonText = text; 170 updateButton(); 171 } 172 173 /** 174 * Returns the button text. 175 */ 176 public String getButtonText() { 177 return mButtonText; 178 } 179 180 /** 181 * Set the button click listener. 182 * 183 * @param clickListener The click listener for the button. 184 */ 185 public void setButtonClickListener(View.OnClickListener clickListener) { 186 mButtonClickListener = clickListener; 187 updateButton(); 188 } 189 190 /** 191 * Returns the button click listener. 192 */ 193 public View.OnClickListener getButtonClickListener() { 194 return mButtonClickListener; 195 } 196 197 @Override 198 public View onCreateView(LayoutInflater inflater, ViewGroup container, 199 Bundle savedInstanceState) { 200 View root = inflater.inflate(R.layout.lb_error_fragment, container, false); 201 202 mErrorFrame = root.findViewById(R.id.error_frame); 203 updateBackground(); 204 205 mImageView = (ImageView) root.findViewById(R.id.image); 206 updateImageDrawable(); 207 208 mTextView = (TextView) root.findViewById(R.id.message); 209 updateMessage(); 210 211 mButton = (Button) root.findViewById(R.id.button); 212 updateButton(); 213 214 mTitleView = (TitleView) root.findViewById(R.id.browse_title_group); 215 updateTitle(); 216 217 FontMetricsInt metrics = getFontMetricsInt(mTextView); 218 int underImageBaselineMargin = container.getResources().getDimensionPixelSize( 219 R.dimen.lb_error_under_image_baseline_margin); 220 setTopMargin(mTextView, underImageBaselineMargin + metrics.ascent); 221 222 int underMessageBaselineMargin = container.getResources().getDimensionPixelSize( 223 R.dimen.lb_error_under_message_baseline_margin); 224 setTopMargin(mButton, underMessageBaselineMargin - metrics.descent); 225 226 return root; 227 } 228 229 private void updateBackground() { 230 if (mErrorFrame != null) { 231 if (mBackgroundDrawable != null) { 232 mErrorFrame.setBackground(mBackgroundDrawable); 233 } else { 234 mErrorFrame.setBackgroundColor(mErrorFrame.getResources().getColor( 235 mIsBackgroundTranslucent ? 236 R.color.lb_error_background_color_translucent : 237 R.color.lb_error_background_color_opaque)); 238 } 239 } 240 } 241 242 private void updateTitle() { 243 if (mTitleView != null) { 244 mTitleView.setTitle(mTitle); 245 mTitleView.setBadgeDrawable(mBadgeDrawable); 246 } 247 } 248 249 private void updateMessage() { 250 if (mTextView != null) { 251 mTextView.setText(mMessage); 252 mTextView.setTextColor(mTextView.getResources().getColor(mIsBackgroundTranslucent ? 253 R.color.lb_error_message_color_on_translucent : 254 R.color.lb_error_message_color_on_opaque)); 255 mTextView.setVisibility(TextUtils.isEmpty(mMessage) ? View.GONE : View.VISIBLE); 256 } 257 } 258 259 private void updateImageDrawable() { 260 if (mImageView != null) { 261 mImageView.setImageDrawable(mDrawable); 262 mImageView.setVisibility(mDrawable == null ? View.GONE : View.VISIBLE); 263 } 264 } 265 266 private void updateButton() { 267 if (mButton != null) { 268 mButton.setText(mButtonText); 269 mButton.setOnClickListener(mButtonClickListener); 270 mButton.setVisibility(TextUtils.isEmpty(mButtonText) ? View.GONE : View.VISIBLE); 271 mButton.requestFocus(); 272 } 273 } 274 275 @Override 276 public void onStart() { 277 super.onStart(); 278 mErrorFrame.requestFocus(); 279 } 280 281 private static FontMetricsInt getFontMetricsInt(TextView textView) { 282 Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG); 283 paint.setTextSize(textView.getTextSize()); 284 paint.setTypeface(textView.getTypeface()); 285 return paint.getFontMetricsInt(); 286 } 287 288 private static void setTopMargin(TextView textView, int topMargin) { 289 ViewGroup.MarginLayoutParams lp = (ViewGroup.MarginLayoutParams) textView.getLayoutParams(); 290 lp.topMargin = topMargin; 291 textView.setLayoutParams(lp); 292 } 293} 294