我们还是先来看看实现好了的效果图吧,
还是一样我们先在attrs文件中写好参数。
<?xml version="1.0" encoding="utf-8"?>
<resources>
<!--定义控件名称所对应的数据类型-->
<attr name="titleText" format="string" />
<attr name="titleTextColor" format="color" />
<attr name="titleTextSize" format="dimension" />
<attr name="image" format="reference"/>
<attr name="imageScaletype">
<enum name="fillXY" value="0"/>
<enum name="center" value="1"/>
</attr>
<!--自定义图文控件-->
<declare-styleable name="MyImageViewTextView">
<attr name="titleText"/>
<attr name="titleTextColor"/>
<attr name="titleTextSize"/>
<attr name="image"/>
<attr name="imageScaletype"/>
</declare-styleable>
</resources>
在看看代码,说实话,在写代码时,在onMeasure()方法中计算有点麻烦啊,一不小心出错了,还有就在再onDraw()方法画的时候,计算更烦啊,哎
public class MyImageViewTextView extends View {
/**
* 文本
*/
private String titleText;
/**
* 文本的颜色
*/
private int titleTextColor;
/**
* 文本大小
*/
private int titleTextSize;
/**
* 绘制时控制整个矩形范围
*/
private Rect rect;
/**
* 控制文本绘制范围
*/
private Rect rectText;
/**
* 设置画笔
*/
private Paint paint;
/**
* 设置图片
*/
private Bitmap bitmap;
private int scale;
/**
* 图片缩放模式
*/
private static final int IMAGE_SCALE_FITXY = 0;
private static final int IMAGE_SCALE_CENTER = 1;
//宽
int width;
//高
int height;
Typeface typeFace;
public MyImageViewTextView(Context context) {
super(context);
}
public MyImageViewTextView(Context context, AttributeSet attrs) {
super(context, attrs);
/**
* 获取自定义控件属性
* */
TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.MyImageViewTextView);
int count = typedArray.getIndexCount();
for (int i = 0; i < count; i++) {
int attr = typedArray.getIndex(i);
switch (attr) {
case R.styleable.MyImageViewTextView_titleText:
titleText = typedArray.getString(attr);
break;
case R.styleable.MyImageViewTextView_titleTextColor:
titleTextColor = typedArray.getColor(attr, Color.RED);
break;
case R.styleable.MyImageViewTextView_titleTextSize:
titleTextSize = typedArray.getDimensionPixelSize(attr, (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP, 16, getResources().getDisplayMetrics()));
break;
case R.styleable.MyImageViewTextView_image:
bitmap = BitmapFactory.decodeResource(getResources(), typedArray.getResourceId(attr, 0));
break;
case R.styleable.MyImageViewTextView_imageScaletype:
scale = typedArray.getInt(attr, 0);
break;
}
}
//资源回收
typedArray.recycle();
rect = new Rect();
rectText = new Rect();
paint = new Paint();
paint.setTextSize(titleTextSize);
paint.getTextBounds(titleText, 0, titleText.length(), rectText);
}
public MyImageViewTextView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
// super.onMeasure(widthMeasureSpec, heightMeasureSpec);
//获取MeasureSpec的模式
int widthMode = MeasureSpec.getMode(widthMeasureSpec);
int widthSize = MeasureSpec.getSize(widthMeasureSpec);
int heightMode = MeasureSpec.getMode(heightMeasureSpec);
int heightSize = MeasureSpec.getSize(heightMeasureSpec);
if (widthMode == MeasureSpec.EXACTLY) {
width = widthSize;
} else {
paint.setTextSize(titleTextSize);
paint.getTextBounds(titleText, 0, titleText.length(), rectText);
//字体宽度
int textWidth = rectText.width() + getPaddingLeft() + getPaddingRight();
//图片宽度
int bitmapWidth = bitmap.getWidth() + getPaddingRight() + getPaddingLeft();
if (widthMode == MeasureSpec.AT_MOST)// wrap_content
{
int desire = Math.max(bitmapWidth, textWidth);
width = Math.min(desire, widthSize);
}
}
if (heightMode == MeasureSpec.EXACTLY) {
height = heightSize;
} else {
paint.setTextSize(titleTextSize);
paint.getTextBounds(titleText, 0, titleText.length(), rectText);
//图片高度加上字体高度 == 总体高度
int textHeight = rectText.height() + bitmap.getHeight() + getPaddingBottom() + getPaddingTop();
height = textHeight;
if (heightMode == MeasureSpec.AT_MOST)// wrap_content
{
height = Math.min(height, heightSize);
}
}
setMeasuredDimension(width, height);
}
@Override
protected void onDraw(Canvas canvas) {
// super.onDraw(canvas);
/**
* 边框
* */
paint.setStrokeWidth(4);
paint.setStyle(Paint.Style.STROKE);
paint.setColor(Color.GREEN);
canvas.drawRect(0, 0, getMeasuredWidth(), getMeasuredHeight(), paint);
//外矩形宽高
rect.left = getPaddingLeft();
rect.right = width - getPaddingRight();
rect.top = getPaddingTop();
rect.bottom = height - getPaddingBottom();
paint.setColor(titleTextColor);
paint.setStyle(Paint.Style.FILL);
canvas.drawText(titleText, width / 2 - rectText.width() / 2, height - getPaddingBottom(), paint);
//减去字体的高
rect.bottom -= rectText.height();
if (scale == IMAGE_SCALE_FITXY) {
canvas.drawBitmap(bitmap, null, rect, paint);
} else {
//计算居中的矩形范围
rect.left = width / 2 - bitmap.getWidth() / 2;
rect.right = width / 2 + bitmap.getWidth() / 2;
rect.top = (height - rectText.height()) / 2 - bitmap.getHeight() / 2;
rect.bottom = (height - rectText.height()) / 2 + bitmap.getHeight() / 2;
canvas.drawBitmap(bitmap, null, rect, paint);
}
}
}
再在布局文件中看看,
<com.tesedome.view.MyImageViewTextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:image="@mipmap/b"
app:imageScaletype="center"
app:titleTextColor="#ffffabac"
android:padding="20dp"
app:titleTextSize="50sp"
app:titleText="我是一朵花。" />
好啦,这样我就实现了图文居中控件,