您的位置:首页 > 移动开发 > Android开发

Android自定义TextView控件

2016-05-06 00:32 453 查看
在网上学习了自定义的控件之后,开始先写一个简单的自定义的TextView.

首先在Android的工程目录的/res/values/下创建attrs.xml,里面的美容如下所示:
<?xml version="1.0" encoding="utf-8"?>

<resources>

<declare-styleable name="myTextView">

<attr name="newText" format="string"/>

<attr name="newTextColor" format="color"/>

<attr name="newTextSize" format="dimension"/>

</declare-styleable>

</resources>


创建Java的class文件,名为AutoTextView.class.内容如下:

import com.xiaojiang.les.R;
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.FontMetricsInt;
import android.graphics.Paint.Style;
import android.graphics.Rect;
import android.util.AttributeSet;
import android.util.TypedValue;
import android.view.View;
public class AutoTextView extends View {
private String text;
private int color;
private float defValue;
private Paint mPaint;
private int size;
private Rect rect;
private int mWidth;
private int mHeight;

public AutoTextView(Context context, AttributeSet attrs) {
this(context, attrs, -1);
}

public AutoTextView(Context context) {
this(context, null);
}

public AutoTextView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);

initAttrs(context, attrs, -1);
}

private void initAttrs(Context context, AttributeSet attrs, int defStyleAttr) {
// 获取自定义属性的数据
TypedArray ta = context.obtainStyledAttributes(attrs, R.styleable.myTextView);
text = ta.getString(R.styleable.myTextView_newText);
color = ta.getColor(R.styleable.myTextView_newTextColor, Color.YELLOW);
defValue = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP, 12, getResources().getDisplayMetrics());
size = (int) ta.getDimension(R.styleable.myTextView_newTextSize, defValue);
ta.recycle();

// 初始化画笔
initPaint();
}

private void initPaint() {
mPaint = new Paint();
// 抗锯齿
mPaint.setAntiAlias(true);
mPaint.setColor(color);
mPaint.setTextSize(size);
mPaint.setStrokeWidth(2);
mPaint.setStyle(Style.FILL);

// 计算文本的宽和高
rect = new Rect();
mPaint.getTextBounds(text, 0, text.length(), rect);

}

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

// super.onMeasure(widthMeasureSpec, heightMeasureSpec);

int wSpec = MeasureSpec.getMode(widthMeasureSpec);
mWidth = MeasureSpec.getSize(widthMeasureSpec);

int hSpec = MeasureSpec.getMode(heightMeasureSpec);
mHeight = MeasureSpec.getSize(heightMeasureSpec);

if (wSpec == MeasureSpec.AT_MOST) {
mWidth = rect.width() + getPaddingLeft() + getPaddingRight();
}

if (hSpec == MeasureSpec.AT_MOST) {
mHeight = rect.height() + getPaddingTop() + getPaddingBottom();
}

setMeasuredDimension(mWidth, mHeight);
}

@Override
protected void onDraw(Canvas canvas) {
// 得到控件的宽和高
mWidth = getWidth();
mHeight = getHeight();
// 进行文本文字开始的设置
FontMetricsInt fontMetrics = mPaint.getFontMetricsInt();
int yStart = (mHeight - fontMetrics.descent - fontMetrics.ascent) / 2;
canvas.drawText(text, (mWidth - rect.width()) / 2, yStart, mPaint);

}
}


3.在activity_main的布局里面,代码如下:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xiaojiang="http://schemas.android.com/apk/res/com.xiaojiang.les"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="${relativePackage}.${activityClass}" >

<com.xiaojiang.les.view.AutoTextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#ffffbb33"
xiaojiang:newText="hello world g"
xiaojiang:newTextColor="#ff0000"
xiaojiang:newTextSize="20sp"/>

</RelativeLayout>


4.好了,准备工作都已经好了,在运行在真机上之后效果很好,但是我想说的是,在上面的代码里面有几点是要注意的:

①就是在activity_main的布局里面我们在引用自定义的控件的时候要注意的是xmlns:xiaojiang=”http://schemas.android.com/apk/res/com.xiaojiang.les” 切勿将最后的格式写成com/xiaojiang/les 那就错了.

②就是View的测量模式. 要区分wrap_content match_parent 和 精确大小的情况 这三种状态下的控件的宽和高要进行区分

③就是关于将文本设置在控件的中心位置的问题 开始的X距离很简单只要记住(控件的宽 - 文本的宽)/2就可以了.但是开始的Y距离就不是那么好算了,可能会出现问题,这里有一个连接分析那个一下 []http://blog.csdn.net/xiandan87/article/details/48106797#0-tsina-1-52987-397232819ff9a47a7b7e80a40613cfe1] 这个是关于drawText()的讲解,但是我研究之后对于这个获得的中间的基线还是心存疑惑,研究的时间长了就不浪费时间了,我总结一下就是这个Y(即上面的yStart ) = (控件的高 - fontMetrics.descent - fontMetrics.ascent)/2 .

其中

fontMetrics.descent表示文本文字从所绘字符的baseline之下至该字符所绘制的最低点

fontMetrics.ascent表示文本文字从所绘字符的baseline之上至该字符所绘制的最高点
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: