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