1 /* 2 * Copyright (C) 2007 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.example.android.apis.view; 18 19 // Need the following import to get access to the app resources, since this 20 // class is in a sub-package. 21 import android.content.Context; 22 import android.content.res.TypedArray; 23 import android.graphics.Canvas; 24 import android.graphics.Paint; 25 import android.util.AttributeSet; 26 import android.view.View; 27 28 import com.example.android.apis.R; 29 30 31 /** 32 * Example of how to write a custom subclass of View. LabelView 33 * is used to draw simple text views. Note that it does not handle 34 * styled text or right-to-left writing systems. 35 * 36 */ 37 public class LabelView extends View { 38 private Paint mTextPaint; 39 private String mText; 40 private int mAscent; 41 42 /** 43 * Constructor. This version is only needed if you will be instantiating 44 * the object manually (not from a layout XML file). 45 * @param context 46 */ 47 public LabelView(Context context) { 48 super(context); 49 initLabelView(); 50 } 51 52 /** 53 * Construct object, initializing with any attributes we understand from a 54 * layout file. These attributes are defined in 55 * SDK/assets/res/any/classes.xml. 56 * 57 * @see android.view.View#View(android.content.Context, android.util.AttributeSet) 58 */ 59 public LabelView(Context context, AttributeSet attrs) { 60 super(context, attrs); 61 initLabelView(); 62 63 TypedArray a = context.obtainStyledAttributes(attrs, 64 R.styleable.LabelView); 65 66 CharSequence s = a.getString(R.styleable.LabelView_text); 67 if (s != null) { 68 setText(s.toString()); 69 } 70 71 // Retrieve the color(s) to be used for this view and apply them. 72 // Note, if you only care about supporting a single color, that you 73 // can instead call a.getColor() and pass that to setTextColor(). 74 setTextColor(a.getColor(R.styleable.LabelView_textColor, 0xFF000000)); 75 76 int textSize = a.getDimensionPixelOffset(R.styleable.LabelView_textSize, 0); 77 if (textSize > 0) { 78 setTextSize(textSize); 79 } 80 81 a.recycle(); 82 } 83 84 private final void initLabelView() { 85 mTextPaint = new Paint(); 86 mTextPaint.setAntiAlias(true); 87 mTextPaint.setTextSize(16); 88 mTextPaint.setColor(0xFF000000); 89 setPadding(3, 3, 3, 3); 90 } 91 92 /** 93 * Sets the text to display in this label 94 * @param text The text to display. This will be drawn as one line. 95 */ 96 public void setText(String text) { 97 mText = text; 98 requestLayout(); 99 invalidate(); 100 } 101 102 /** 103 * Sets the text size for this label 104 * @param size Font size 105 */ 106 public void setTextSize(int size) { 107 mTextPaint.setTextSize(size); 108 requestLayout(); 109 invalidate(); 110 } 111 112 /** 113 * Sets the text color for this label. 114 * @param color ARGB value for the text 115 */ 116 public void setTextColor(int color) { 117 mTextPaint.setColor(color); 118 invalidate(); 119 } 120 121 /** 122 * @see android.view.View#measure(int, int) 123 */ 124 @Override 125 protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { 126 setMeasuredDimension(measureWidth(widthMeasureSpec), 127 measureHeight(heightMeasureSpec)); 128 } 129 130 /** 131 * Determines the width of this view 132 * @param measureSpec A measureSpec packed into an int 133 * @return The width of the view, honoring constraints from measureSpec 134 */ 135 private int measureWidth(int measureSpec) { 136 int result = 0; 137 int specMode = MeasureSpec.getMode(measureSpec); 138 int specSize = MeasureSpec.getSize(measureSpec); 139 140 if (specMode == MeasureSpec.EXACTLY) { 141 // We were told how big to be 142 result = specSize; 143 } else { 144 // Measure the text 145 result = (int) mTextPaint.measureText(mText) + getPaddingLeft() 146 + getPaddingRight(); 147 if (specMode == MeasureSpec.AT_MOST) { 148 // Respect AT_MOST value if that was what is called for by measureSpec 149 result = Math.min(result, specSize); 150 } 151 } 152 153 return result; 154 } 155 156 /** 157 * Determines the height of this view 158 * @param measureSpec A measureSpec packed into an int 159 * @return The height of the view, honoring constraints from measureSpec 160 */ 161 private int measureHeight(int measureSpec) { 162 int result = 0; 163 int specMode = MeasureSpec.getMode(measureSpec); 164 int specSize = MeasureSpec.getSize(measureSpec); 165 166 mAscent = (int) mTextPaint.ascent(); 167 if (specMode == MeasureSpec.EXACTLY) { 168 // We were told how big to be 169 result = specSize; 170 } else { 171 // Measure the text (beware: ascent is a negative number) 172 result = (int) (-mAscent + mTextPaint.descent()) + getPaddingTop() 173 + getPaddingBottom(); 174 if (specMode == MeasureSpec.AT_MOST) { 175 // Respect AT_MOST value if that was what is called for by measureSpec 176 result = Math.min(result, specSize); 177 } 178 } 179 return result; 180 } 181 182 /** 183 * Render the text 184 * 185 * @see android.view.View#onDraw(android.graphics.Canvas) 186 */ 187 @Override 188 protected void onDraw(Canvas canvas) { 189 super.onDraw(canvas); 190 canvas.drawText(mText, getPaddingLeft(), getPaddingTop() - mAscent, mTextPaint); 191 } 192 } 193