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