<转 http://www.eoeandroid.com/forum.php?mod=viewthread&tid=306320>
很多公司都会问到自定义控件的问题,自定义控件无非三种方式: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>