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         // 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      */
     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      */
    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      */
    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
    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      */
    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      */
    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
    190     protected void onDraw(Canvas canvas) {
    191         super.onDraw(canvas);
    192         canvas.drawText(mText, getPaddingLeft(), getPaddingTop() - mAscent, mTextPaint);
    193     }
    194 }
    195