实现自定义的View,有以下步骤:
1、在res/values下创建文件attr.xml文件,文件内容为:
<?xml version="1.0" encoding="utf-8"?>
<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是<declare-styleable //name="customView">的id
TypedArray a=context.obtainStyledAttributes(attrs, R.styleable.customView);
//获取自定义属性的个数
int n=a.getIndexCount();
for(int i=0;i<n;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<Integer> set = new HashSet<Integer>();
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,代码如下
<RelativeLayout xmlns:android="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"
/>
</RelativeLayout>
必须声明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);
效果图如下:
源码下载地址:http://download.csdn.net/detail/a_person_alone/9488356