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 */ LabelView(Context context)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 */ LabelView(Context context, AttributeSet attrs)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 initLabelView()84 private final void initLabelView() { 85 mTextPaint = new Paint(); 86 mTextPaint.setAntiAlias(true); 87 // Must manually scale the desired text size to match screen density 88 mTextPaint.setTextSize(16 * getResources().getDisplayMetrics().density); 89 mTextPaint.setColor(0xFF000000); 90 setPadding(3, 3, 3, 3); 91 } 92 93 /** 94 * Sets the text to display in this label 95 * @param text The text to display. This will be drawn as one line. 96 */ setText(String text)97 public void setText(String text) { 98 mText = text; 99 requestLayout(); 100 invalidate(); 101 } 102 103 /** 104 * Sets the text size for this label 105 * @param size Font size 106 */ setTextSize(int size)107 public void setTextSize(int size) { 108 // This text size has been pre-scaled by the getDimensionPixelOffset method 109 mTextPaint.setTextSize(size); 110 requestLayout(); 111 invalidate(); 112 } 113 114 /** 115 * Sets the text color for this label. 116 * @param color ARGB value for the text 117 */ setTextColor(int color)118 public void setTextColor(int color) { 119 mTextPaint.setColor(color); 120 invalidate(); 121 } 122 123 /** 124 * @see android.view.View#measure(int, int) 125 */ 126 @Override onMeasure(int widthMeasureSpec, int heightMeasureSpec)127 protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { 128 setMeasuredDimension(measureWidth(widthMeasureSpec), 129 measureHeight(heightMeasureSpec)); 130 } 131 132 /** 133 * Determines the width of this view 134 * @param measureSpec A measureSpec packed into an int 135 * @return The width of the view, honoring constraints from measureSpec 136 */ measureWidth(int measureSpec)137 private int measureWidth(int measureSpec) { 138 int result = 0; 139 int specMode = MeasureSpec.getMode(measureSpec); 140 int specSize = MeasureSpec.getSize(measureSpec); 141 142 if (specMode == MeasureSpec.EXACTLY) { 143 // We were told how big to be 144 result = specSize; 145 } else { 146 // Measure the text 147 result = (int) mTextPaint.measureText(mText) + getPaddingLeft() 148 + getPaddingRight(); 149 if (specMode == MeasureSpec.AT_MOST) { 150 // Respect AT_MOST value if that was what is called for by measureSpec 151 result = Math.min(result, specSize); 152 } 153 } 154 155 return result; 156 } 157 158 /** 159 * Determines the height of this view 160 * @param measureSpec A measureSpec packed into an int 161 * @return The height of the view, honoring constraints from measureSpec 162 */ measureHeight(int measureSpec)163 private int measureHeight(int measureSpec) { 164 int result = 0; 165 int specMode = MeasureSpec.getMode(measureSpec); 166 int specSize = MeasureSpec.getSize(measureSpec); 167 168 mAscent = (int) mTextPaint.ascent(); 169 if (specMode == MeasureSpec.EXACTLY) { 170 // We were told how big to be 171 result = specSize; 172 } else { 173 // Measure the text (beware: ascent is a negative number) 174 result = (int) (-mAscent + mTextPaint.descent()) + getPaddingTop() 175 + getPaddingBottom(); 176 if (specMode == MeasureSpec.AT_MOST) { 177 // Respect AT_MOST value if that was what is called for by measureSpec 178 result = Math.min(result, specSize); 179 } 180 } 181 return result; 182 } 183 184 /** 185 * Render the text 186 * 187 * @see android.view.View#onDraw(android.graphics.Canvas) 188 */ 189 @Override onDraw(Canvas canvas)190 protected void onDraw(Canvas canvas) { 191 super.onDraw(canvas); 192 canvas.drawText(mText, getPaddingLeft(), getPaddingTop() - mAscent, mTextPaint); 193 } 194 } 195