Android自定义TextView控件
2016-05-06 00:32
453 查看
在网上学习了自定义的控件之后,开始先写一个简单的自定义的TextView.
首先在Android的工程目录的/res/values/下创建attrs.xml,里面的美容如下所示:
创建Java的class文件,名为AutoTextView.class.内容如下:
3.在activity_main的布局里面,代码如下:
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之上至该字符所绘制的最高点
首先在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之上至该字符所绘制的最高点
相关文章推荐
- Android中通过浏览器直接打开应用
- Android源码解析——Toast
- IPC(跨进程)基础知识
- Android源码解析——Toast
- Android源码解析——Toast
- 在Android上使用官方Lambda支持 - Android N & Jack工具(兼容旧平台)
- Android登陆页面,获取验证码按钮的实现
- Jni编写清晰流程
- Android缓存的引用
- Android Studio开发遇到的问题(持续更新ing)
- Android 杂技
- android音乐播放器之在线播放功能的实现
- 本博客纯粹记录自己的java,Android学习过程
- Android LayoutInflater详解
- Android中的单元测试
- 使用klogctl接口离线保存android kernel log
- AndroidRuntime: java.lang.IllegalAccessError: tried to access class android.content.res.StringBlock
- [置顶] android开发之集成zxing,二维码,以及扫描二维码的功能实现。带源代码下载
- android 常用的adb命令
- MVP模式在Android开发中的应用