实现自定义的View

实现自定义的View,有以下步骤:
1、在res/values下创建文件attr.xml文件,文件内容为:


<resources>
    <attr name="titleText" format="string"/>
    <attr name="titleTextColor" format="color"/>
    <attr name="titleTextSize" format="dimension"/>

    <declare-styleable name="customView">
         <attr name="titleText" />
        <attr name="titleTextColor" />
        <attr name="titleTextSize" />
    declare-styleable>
resources>

用attr定义下字体,字体颜色,字体大小三个属性,name为名字,format为形式,形式有string,color,demension,integer,enum,reference,float,boolean,fraction,flag这几种。然后在declare-styleable中声明自定义的view的名字,这里是customView,这里的名字可以随意给。declare-styleable中attr是声明上述定义的属性,不用format。

2、创建一个类extends View,并实现onMeasure()和onDraw(),onMeasure方式是实现自定义的view的长和宽的方法,onDraw()是绘制view的方法。

3、重要的是还要写构造方法。在View的构造方法中获得我们自定义的属性,代码如下:

package com.zengfeng.customview.view;

import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Rect;
import android.util.AttributeSet;
import android.util.Log;
import android.util.TypedValue;
import android.view.View;
import android.view.View.MeasureSpec;
import android.view.View.OnClickListener;

import java.util.HashSet;
import java.util.Random;
import java.util.Set;

import com.zengfeng.customview.R;

public class CustomView extends View{

    //文本
    private String titleText;
    //文本的颜色
    private int titleTextColor;
    //文本的字体大小
    private int titleTextSize;
    //绘制时控制文本的范围
    private Rect rect;
    //绘制笔
    private Paint paint;

    //构造器,获得自定义的属性
    public CustomView(Context context, AttributeSet attrs) {
        super(context, attrs);

        //获取自定义attr.xml文件的属性列表,
        //R.styleable.customView是的id
        TypedArray a=context.obtainStyledAttributes(attrs, R.styleable.customView);
        //获取自定义属性的个数
        int n=a.getIndexCount();

        for(int i=0;i//获取自定义
            int attr=a.getIndex(i);

            switch(attr){
                //如果是获取到文本的属性
                case R.styleable.customView_titleText:
                    titleText=a.getString(attr);
                    break;
                //如果是文本的颜色
                case R.styleable.customView_titleTextColor:
                    titleTextColor=a.getColor(attr, Color.BLACK);
                    break;
                //如果是文本的文字的大小
                case R.styleable.customView_titleTextSize:
                    titleTextSize=a.getDimensionPixelSize(attr, 
                            (int) TypedValue.applyDimension(
                            TypedValue.COMPLEX_UNIT_SP, 
                            16, getResources().getDisplayMetrics()));
                    break;
            }
        }
        //使自定义属性列表可复用,一定要调用这个方法
        a.recycle();
        //画笔
        paint=new Paint();
        //设置画笔的粗细
        paint.setTextSize(titleTextSize);

        //设置文本的范围
        rect=new Rect();
        paint.getTextBounds(titleText, 0, titleText.length(), rect);
        //设置点击事件
        this.setOnClickListener(new OnClickListener(){

            @Override
            public void onClick(View v)
            {
                titleText = randomText();
                postInvalidate();
                requestLayout();
            }

        });

    }

    //生成随机数
    private String randomText(){
        Random random = new Random();
        Set set = new HashSet();
        while (set.size() < 4){
            int randomInt = random.nextInt(10);
            set.add(randomInt);
        }
        StringBuffer sb = new StringBuffer();
        for (Integer i : set){
            sb.append("" + i);
        }

        return sb.toString();
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {


        int width=0;
        int height=0;

        /*
         * 设置宽度
         */
        //获取宽度的模式
        int specMod=MeasureSpec.getMode(widthMeasureSpec);
        int SpecSize=MeasureSpec.getSize(widthMeasureSpec);
        switch (specMod) {
        //如果是指定的具体数值.
        case MeasureSpec.EXACTLY:
                width=getPaddingLeft()+getPaddingRight()+SpecSize;
            break;
        //如果为warp_content
        case MeasureSpec.AT_MOST:
                width=getPaddingLeft()+getPaddingRight()+rect.width();
                break;

        }

        /**
         * 设置高度
         */
        specMod = MeasureSpec.getMode(heightMeasureSpec);
        SpecSize = MeasureSpec.getSize(heightMeasureSpec);
        switch (specMod){
        //如果是指定的具体数值,
        case MeasureSpec.EXACTLY:
            height = getPaddingTop() + getPaddingBottom() + SpecSize;
            break;
            //如果为warp_content
        case MeasureSpec.AT_MOST:
            height = getPaddingTop() + getPaddingBottom() + rect.height();
            break;
        }

        //设置自定义view的长和宽,这个方法必须调用,要不会出现异常
        setMeasuredDimension(width, height);
    }

    @Override
    protected void onDraw(Canvas canvas) {

        //绘制文本的范围,颜色蓝色
        paint.setColor(Color.BLUE);
        canvas.drawRect(0, 0,getMeasuredWidth(), getMeasuredHeight(),paint);

        //绘制字体
        paint.setColor(titleTextColor);
        canvas.drawText(titleText, getWidth() / 2 - rect.width() / 2, getHeight() / 2 + rect.height() / 2, paint);
    }

}

4、在activity_main.xml布局中使用自定义的view,代码如下

"http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    xmlns:zengfeng="http://schemas.android.com/apk/res/com.zengfeng.customview"
    android:layout_width="match_parent"
    android:layout_height="match_parent" >

  <com.zengfeng.customview.view.CustomView 
       android:layout_width="match_parent"
       android:layout_height="match_parent"
       zengfeng:titleText="4561"
       android:padding="10dp"
       zengfeng:titleTextColor="#fffeee"
       android:layout_centerInParent="true"
       zengfeng:titleTextSize="40sp" 
      />


必须声明xmlns:zengfeng=”http://schemas.android.com/apk/res/com.zengfeng.customview”,其中com.zengfeng.customview为控件的包名。zengfeng这个对应上述的xmlns:zengfeng;zengfeng:titleText=”4561”, zengfeng:titleTextColor=”#fffeee”,zengfeng:titleTextSize=”40sp” 使用自定义的属性。

最后在oncreate中加载布布局setContentView(R.layout.activity_main);
效果图如下:

实现自定义的View_第1张图片

源码下载地址:http://download.csdn.net/detail/a_person_alone/9488356

你可能感兴趣的:(Android)