Home | History | Annotate | Download | only in view
      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