概述
【1】自定义View的属性 :
在res/values下新建一个attrs.xml文件,在里面定义我们的属性
<?xml version="1.0" encoding="utf-8"?>
<resources>
<attr name="titleText" format="string"/>
<attr name="titleTextColor" format="color"/>
<attr name="backColor" format="color"/>
<attr name="titleTextSize" format="dimension"/>
<declare-styleable name="CustomCircleView">
<attr name="titleText"/>
<attr name="titleTextColor"/>
<attr name="titleTextSize"/>
<attr name="backColor"/>
</declare-styleable>
</resources>
在布局定义View,这里定义了5个:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
>
<com.dhl.customview.view.CustomCircleView
android:layout_width="100dp"
android:layout_height="100dp"
app:titleText="123456"
app:titleTextColor="@color/colorAccent"
android:padding="5dp"
android:layout_marginLeft="30dp"
android:layout_centerInParent="true"
app:titleTextSize="14sp"
/>
<com.dhl.customview.view.CustomCircleView
android:layout_width="100dp"
android:layout_height="100dp"
app:titleText="123456"
app:titleTextColor="@color/colorAccent"
android:padding="5dp"
android:layout_marginLeft="30dp"
android:layout_alignParentRight="true"
app:titleTextSize="18sp"
/>
<com.dhl.customview.view.CustomCircleView
android:layout_width="100dp"
android:layout_height="100dp"
app:titleText="123456"
app:titleTextColor="@color/colorAccent"
android:padding="5dp"
android:layout_marginLeft="30dp"
app:backColor="#abdc25"
android:layout_alignParentLeft="true"
app:titleTextSize="18sp"
/>
<com.dhl.customview.view.CustomCircleView
android:layout_width="100dp"
android:layout_height="100dp"
app:titleText="123456"
app:titleTextColor="@color/colorAccent"
android:padding="5dp"
android:layout_marginLeft="30dp"
android:layout_alignParentBottom="true"
android:layout_alignParentRight="true"
app:titleTextSize="18sp"
/>
<com.dhl.customview.view.CustomCircleView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:titleText="123456"
app:titleTextColor="@color/colorAccent"
android:padding="5dp"
android:layout_marginLeft="30dp"
app:backColor="#abdc25"
android:layout_alignParentBottom="true"
android:layout_alignParentLeft="true"
app:titleTextSize="18sp"
/>
</RelativeLayout>
【2】在构造方法中获取自定义属性:
public CustomCircleView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
TypedArray a= context.getTheme().obtainStyledAttributes(attrs, R.styleable.CustomCircleView,defStyleAttr,0);
/**
* 这个获得是你实际在layout中设置的属性个数
*/
int n = a.getIndexCount();
for(int i = 0;i<n;i++)
{
int attr = a.getIndex(i);
switch (attr)
{
case R.styleable.CustomCircleView_titleText:
titleText = a.getString(attr);
break;
case R.styleable.CustomCircleView_titleTextColor:
titleColor = a.getColor(attr, Color.BLACK);
break;
case R.styleable.CustomCircleView_backColor:
backColor = a.getColor(attr,Color.GREEN);
break;
case R.styleable.CustomCircleView_titleTextSize:
titleSize = a.getDimensionPixelSize(attr,(int) TypedValue.applyDimension(
TypedValue.COMPLEX_UNIT_SP, 16, getResources().getDisplayMetrics()));
break;
}
}
a.recycle();
mPaint = new Paint();
mPaint.setTextSize(titleSize);
mBound = new Rect();
/**
* 获得绘制文本的宽和高
*/
mPaint.getTextBounds(titleText, 0, titleText.length(), mBound);
}
获取自定义属性,并且遍历每个属性,set相应的值。
【3】重写onMeasure:
MeasureSpce的mode有三种:EXACTLY, AT_MOST,UNSPECIFIED,EXACTLY顾名思义,有了准确的值,一般是固定的宽高度或者match_parent。AT_MOST表示在一个范围内,一般为wrap_content。UNSPECIFIED表示View能有多大就多大,很少用到。
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
Log.e(TAG,"onMeasure");
int width = getMySize(100,widthMeasureSpec);
int height = getMySize(100,heightMeasureSpec);
setMeasuredDimension(width, height);
}
封装计算相应的宽高
/**
* 计算相应的宽高
* @param defaultSize 默认值
* @param measureSpec
* @return
*/
private int getMySize(int defaultSize, int measureSpec) {
int mySize = defaultSize;
int mode = MeasureSpec.getMode(measureSpec);
int size = MeasureSpec.getSize(measureSpec);
switch (mode) {
case MeasureSpec.UNSPECIFIED: {//如果没有指定大小,就设置为默认大小
mySize = defaultSize;
break;
}
case MeasureSpec.AT_MOST: {//如果测量模式是最大取值为size
//我们将自己计算View的大小
mPaint.setTextSize(titleSize);
mPaint.getTextBounds(titleText, 0, titleText.length(), mBound);
float textWidth = mBound.width();
int desired = (int) (getPaddingLeft() + textWidth + getPaddingRight());
mySize = desired;
break;
}
case MeasureSpec.EXACTLY: {//如果是固定的大小,那就不要去改变它
mySize = size;
break;
}
}
return mySize;
}
主要是对 AT_MOST这种情况的处理,这个处理好了,View的宽和高就是对的。
【4】重写onDraw():
这个主要是把相应View绘制出来,
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
Log.e(TAG,"onDraw");
//圆的半径
int r = Math.min(getMeasuredWidth() / 2,getMeasuredHeight()/2);
//圆心的横坐标
int centerX =r;
//圆心的纵坐标
int centerY =r;
Paint paint = new Paint();
paint.setColor(Color.GREEN);
mPaint.setColor(backColor);
//绘制圆
canvas.drawCircle(centerX, centerY, r, mPaint);
mPaint.setColor(titleColor);
//绘制Text
canvas.drawText(titleText, getWidth() / 2 - mBound.width() / 2, getHeight() / 2 + mBound.height() / 2, mPaint);
}
一个圆形的TextView就此完成,下面贴出全部代码:
public class CustomCircleView extends View {
private static final String TAG = CustomCircleView.class.getSimpleName();
/**
* 文本
*/
private String titleText ;
/**
* 字体颜色
*/
private int titleColor =Color.BLACK ;
/**
* 背景颜色,设置默认颜色
*/
private int backColor = Color.GRAY;
/**
* 色值
*/
private int titleSize ;
/**
*控制文本的范围
*/
private Rect mBound;
private Paint mPaint;
public CustomCircleView(Context context) {
this(context, null);
}
public CustomCircleView(Context context, @Nullable AttributeSet attrs) {
this(context, attrs, 0);
}
public CustomCircleView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
TypedArray a= context.getTheme().obtainStyledAttributes(attrs, R.styleable.CustomCircleView,defStyleAttr,0);
/**
* 这个获得是你实际在layout中设置的属性个数
*/
int n = a.getIndexCount();
for(int i = 0;i<n;i++)
{
int attr = a.getIndex(i);
switch (attr)
{
case R.styleable.CustomCircleView_titleText:
titleText = a.getString(attr);
break;
case R.styleable.CustomCircleView_titleTextColor:
titleColor = a.getColor(attr, Color.BLACK);
break;
case R.styleable.CustomCircleView_backColor:
backColor = a.getColor(attr,Color.GREEN);
break;
case R.styleable.CustomCircleView_titleTextSize:
titleSize = a.getDimensionPixelSize(attr,(int) TypedValue.applyDimension(
TypedValue.COMPLEX_UNIT_SP, 16, getResources().getDisplayMetrics()));
break;
}
}
a.recycle();
mPaint = new Paint();
mPaint.setTextSize(titleSize);
mBound = new Rect();
/**
* 获得绘制文本的宽和高
*/
mPaint.getTextBounds(titleText, 0, titleText.length(), mBound);
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
Log.e(TAG,"onDraw");
//圆的半径
int r = Math.min(getMeasuredWidth() / 2,getMeasuredHeight()/2);
//圆心的横坐标
int centerX =r;
//圆心的纵坐标
int centerY =r;
Paint paint = new Paint();
paint.setColor(Color.GREEN);
mPaint.setColor(backColor);
//绘制圆
canvas.drawCircle(centerX, centerY, r, mPaint);
mPaint.setColor(titleColor);
//绘制Text
canvas.drawText(titleText, getWidth() / 2 - mBound.width() / 2, getHeight() / 2 + mBound.height() / 2, mPaint);
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
Log.e(TAG,"onMeasure");
int width = getMySize(100,widthMeasureSpec);
int height = getMySize(100,heightMeasureSpec);
setMeasuredDimension(width, height);
}
/**
* 计算相应的宽高
* @param defaultSize 默认值
* @param measureSpec
* @return
*/
private int getMySize(int defaultSize, int measureSpec) {
int mySize = defaultSize;
int mode = MeasureSpec.getMode(measureSpec);
int size = MeasureSpec.getSize(measureSpec);
switch (mode) {
case MeasureSpec.UNSPECIFIED: {//如果没有指定大小,就设置为默认大小
mySize = defaultSize;
break;
}
case MeasureSpec.AT_MOST: {//如果测量模式是最大取值为size
//我们将自己计算View的大小
mPaint.setTextSize(titleSize);
mPaint.getTextBounds(titleText, 0, titleText.length(), mBound);
float textWidth = mBound.width();
int desired = (int) (getPaddingLeft() + textWidth + getPaddingRight());
mySize = desired;
break;
}
case MeasureSpec.EXACTLY: {//如果是固定的大小,那就不要去改变它
mySize = size;
break;
}
}
return mySize;
}
public void setTitleText(String str)
{
titleText = str ;
invalidate();
}
}
OK,下面贴出效果图
如有问题,请留言。。。
最后
以上就是威武玉米为你收集整理的自定义View之圆形TextView的全部内容,希望文章能够帮你解决自定义View之圆形TextView所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复