【安卓开发】自定义控件

作者:Young.Liu 分类: 技术 发布于:2013-9-30 17:14 ė2054次浏览 60条评论
  很多公司都会问到自定义控件的问题,自定义控件无非三种方式:1.继承view 2.继承原有的控件 在原有控件的基础上进行修改 3.组件拼装组合 后两种暂且不说,原理的问题都需要知道,在此,小弟我分享通过继承View,而写的TextView,千万别小看他奥 ,这个可是基础,再次我也写的很详细

   第一步:自定义属性 自定义属性就是在res/values/目录下创建一个attrs的xml文件


<?xml version="1.0" encoding="utf-8"?>
<resources>
    <declare-styleable name="MyTestView"> 
        <attr name="textColor" format="color"/> 
        <attr name="textSize" format="dimension"/> 
        <attr name="text" format="string"></attr>
        <attr name="background" format="reference|color"/>
    </declare-styleable> 
    
</resources>


<declare-styleable name="MyTestView"> 这个标签是必须要有的里面的name就是我自定义控件的名称,前面的标签就是一个字母也不能错
    里面的format http://blog.chinaunix.net/uid-20484604-id-2980081.html这是参考
     第二部:写一个类继承View


package com.example.demo;

import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Paint.FontMetrics;
import android.graphics.Typeface;
import android.text.TextPaint;
import android.util.AttributeSet;
import android.view.View;

//
public class MyTextView extends View
{
    //定义画笔
    private TextPaint mPaint = null;
    //要绘制的内容
    private String text = null;
    //背景
    private int background;
    
    public MyTextView(Context context, AttributeSet attrs)
    {
        super(context, attrs);
        //绘制文本  Paint.ANTI_ALIAS_FLAG这个属性来帮助消除锯齿使其边缘更平滑
        mPaint = new TextPaint(Paint.ANTI_ALIAS_FLAG);
        //获取属性的数组 在自定义view的代码中引入自定义属性,修改构造函数
        //context通过调用obtainStyledAttributes方法来获取一个TypeArray,然后由该TypeArray来对属性进行设置

        TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.MyTestView);
        
        //获取设置的颜色和文字大小 这里的获取其实就是在main.xml中获取的见下面代码,至于 0XFFFFFFFF ,14是defalut默认值
        int textColor = a.getColor(R.styleable.MyTestView_textColor, 0XFFFFFFFF);
        float textSize = a.getDimension(R.styleable.MyTestView_textSize, 14);
        text = a.getString(R.styleable.MyTestView_text);
        mPaint.setTextSize(textSize);
        mPaint.setColor(textColor);
        background = Color.WHITE;
        a.recycle(); //记住这一部千万不要忘记 
    }
    
    @Override
    protected void onDraw(Canvas canvas)
    {
        super.onDraw(canvas);
        //清屏幕
        canvas.drawColor(background);
        mPaint.setTypeface(Typeface.DEFAULT);//特别强调一点这个方法是设置字体样式Typeface.DEFAULT:默认字体 Typeface.DEFAULT_BOLD:加粗字体 Typeface.MONOSPACE:monospace字体。
       // Typeface.SANS_SERIF:sans字体   // Typeface.SERIF:serif字体
            
        //需要根据文字长度控制换行
        //测量文字的长度
        float  trueSize = mPaint.measureText(text);
        //设置一行像素
        int lineW = this.getWidth();
        //计算共绘制多少行
        int count = 0;
        if(trueSize>(int)trueSize){
            count =((int)trueSize/lineW)+1;
        }else{
            count = (int)trueSize/lineW;
        }
        FontMetrics fm = mPaint.getFontMetrics();       
        int hSize = (int)Math.ceil(fm.descent - fm.ascent)/2;
        //开始索引
        int startIndex = 0;
        String lineText = null;
        for(int i=0;i<=count;i++){
            //计算坐标
            int x =2;
            int y = hSize*i+2+30;
            if(i!=count){
                int endIndex=subStringLength(text, lineW, mPaint);
                lineText = text.substring(0,endIndex);
                canvas.drawText(lineText, x, y, mPaint);
                text = text.substring(endIndex);
            }else{
                lineText = text.substring(startIndex);
                canvas.drawText(lineText, x, y, mPaint);
                break;
            }
        }
                   

                       
    }
    public static int subStringLength(String value,int maxL,TextPaint paint){
        int currentInext = 0;
        for(int i=0;i<value.length();i++){
            //获取一个字符
            String temp = value.substring(0,i+1);
            //测量真是长度
            float valueLength = paint.measureText(temp);
            if(valueLength > maxL){
                currentInext = i;
                break;
            }
        }
        return currentInext;
    }
    
}
之后在就可以拿来用了
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
   xmlns:mview = "http://schemas.android.com/apk/res/com.example.demo"
   android:orientation="vertical"
   android:layout_width="fill_parent"
   android:layout_height="fill_parent"
   >

   <com.example.demo.MyTextView
       android:layout_width="fill_parent"
       android:layout_height="wrap_content"
       mview:textColor="@android:color/darker_gray"
       mview:textSize="20sp"
       mview:text="hello world"
       />

</LinearLayout>


本文出自 我的技术积累,转载时请注明出处及相应链接。


Ɣ回顶部