属性文件:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<attr name="titleText" format="string"></attr>
<attr name="titleTextSize" format="dimension"></attr>
<attr name="textColor" format="color"></attr>
<attr name="image" format="reference"></attr>
<attr name="imageScaleType" >
<enum name="fillXY" value="0"></enum>
<enum name="center" value="1"></enum>
</attr>
<declare-styleable name="CustomImageView">
<attr name="titleText"/>
<attr name="titleTextSize"/>
<attr name="textColor"/>
<attr name="image"/>
<attr name="imageScaleType"/>
</declare-styleable>
</resources>
实现类:
public class CustomImageView extends ImageView {
private Bitmap mImg;
private String mText;
private int mColor;
private int mSize;
private Rect mBound;//绘制文本的范围
private Paint mPaint;
private int mImgScale;//0 fill填充 1 居中对齐
private Rect rect; //图片范围
private int width;
private int height;
public CustomImageView(Context context) {
this(context,null);
}
public CustomImageView(Context context, AttributeSet attrs) {
this(context,attrs,0);
}
public CustomImageView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
TypedArray ta = context.getTheme().obtainStyledAttributes(attrs,R.styleable.CustomImageView,defStyleAttr,0);
int n = ta.getIndexCount();
for(int i = 0; i < n; i++){
int attr = ta.getIndex(i);
switch (attr){
case R.styleable.CustomImageView_image:
mImg = BitmapFactory.decodeResource(getResources(),ta.getResourceId(attr,0));
break;
case R.styleable.CustomImageView_imageScaleType:
mImgScale = ta.getInt(attr,0);
break;
case R.styleable.CustomImageView_titleText:
mText = ta.getString(attr);
break;
case R.styleable.CustomImageView_textColor:
mColor = ta.getColor(attr, Color.BLACK);
break;
case R.styleable.CustomImageView_titleTextSize:
mSize = ta.getDimensionPixelSize(attr,(int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP,16,getResources().getDisplayMetrics()));
break;
}
}
ta.recycle();
rect = new Rect();
mPaint = new Paint();
mBound = new Rect();
mPaint.setTextSize(mSize);
mPaint.getTextBounds(mText, 0, mText.length(),mBound);
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
//super.onMeasure(widthMeasureSpec, heightMeasureSpec);
//设置宽度
/*
* 当设置为wrap_content
* 取宽度为图片 和字体的宽度的最大值
* 这个值不能大于 父控件给定的值 取和父控件的最小值
* 当文本宽度大于图片长度 大于控件长度 就会显示xx....
* 当图片宽度大于文本长度小于控件长度显示
* //当图片宽度大于文本长度 大于控件长度应该剪裁图片
* */
int specMode = MeasureSpec.getMode(widthMeasureSpec);
int specSize = MeasureSpec.getSize(widthMeasureSpec);//父布局给的宽度
if(specMode == MeasureSpec.EXACTLY){//match_parent,accurate 精确值
//固定宽度 高度 specSize 为3倍的固定宽高 不知道为什么?
width = specSize;
Log.d("gac","img width"+mImg.getWidth());
Log.d("gac","specSizeWidth:"+specSize);
}else{
//由图片决定宽度
int desiredImg = getPaddingLeft()+getPaddingRight()+mImg.getWidth();
//由字体决定的宽度
int desiredText = getPaddingLeft()+getPaddingRight()+mBound.width();
if(specMode == MeasureSpec.AT_MOST){//wrap_content
int desire = Math.max(desiredImg,desiredText);
width = Math.min(desire,specSize);
/*MeasureSpec.AT_MOST模式表示你的宽度不能超过父控件给定的值即specSize
* */
}else{
width = specSize;
Log.d("gac","specSizeWidth:"+specSize);
}
}
//设置高度
specMode = MeasureSpec.getMode(heightMeasureSpec);
specSize = MeasureSpec.getSize(heightMeasureSpec);
if(specMode == MeasureSpec.EXACTLY){
//固定宽度 高度 specSize 为3倍的固定宽高 不知道为什么?
height = specSize;
Log.d("gac","specSizeHeight:"+specSize);
}else{
int desire = getPaddingTop() + getPaddingBottom() + mImg.getHeight() + mBound.height();
if (specMode == MeasureSpec.AT_MOST)// wrap_content
{
height = Math.min(desire, specSize);
}else{
height = specSize;
Log.d("gac","specSizeHeight:"+specSize);
}
}
setMeasuredDimension(width,height);
}
@Override
protected void onDraw(Canvas canvas) {
// super.onDraw(canvas);
mPaint.setStrokeWidth(4);
mPaint.setStyle(Paint.Style.STROKE);
mPaint.setColor(Color.CYAN);
canvas.drawRect(0, 0, getMeasuredWidth(), getMeasuredHeight(), mPaint);
rect.left = getPaddingLeft();
rect.right = width - getPaddingRight();
rect.top = getPaddingTop();
rect.bottom = height - getPaddingBottom();
mPaint.setColor(mColor);
mPaint.setStyle(Paint.Style.FILL);
/**
* 当字体宽度大于控件宽度
* 当前设置的宽度小于字体需要的宽度,将字体改为xxx...
*/
if(mBound.width() > width){
TextPaint paint = new TextPaint(mPaint);
String msg = TextUtils.ellipsize(mText,paint,(float)width - getPaddingLeft()-getPaddingRight(),TextUtils.TruncateAt.END).toString();
canvas.drawText(msg,getPaddingLeft(),height - getPaddingBottom(),mPaint);
}else{
//正常情况字体居中
canvas.drawText(mText,width/2-mBound.width()*1.0f/2,height - getPaddingBottom(),mPaint);
}
/*
* 当图片宽度大于控件宽度应该剪裁图片
* */
//取消使用掉的块 图片不要画到下面的文字
rect.bottom -=mBound.height();
if(mImgScale == 0){//fillxy
canvas.drawBitmap(mImg,null,rect,mPaint);
}else if(mImgScale == 1 && width > mImg.getWidth()) {
//计算居中的矩形范围
Log.d("gac","imgwidth" +mImg.getWidth() +" width"+width);
rect.left = width / 2 - mImg.getWidth() / 2;//图片左上角x坐标 (width-mImgWidth)/2
rect.right = width / 2 + mImg.getWidth() / 2;//图片右上角x坐标 (width-mImgWidth)/2+mImgWidth
rect.top = (height - mBound.height()) / 2 - mImg.getHeight() / 2;//图片顶部坐标 y轴坐标 (总高度- 字体高度-图片高度)/2
rect.bottom = (height - mBound.height()) / 2 + mImg.getHeight() / 2;//图片底部y坐标 (总高度-字体高度-图片高度)/2+图片高度
canvas.drawBitmap(mImg, null, rect, mPaint);
}else if(mImgScale == 1 && (mImg.getWidth() > width)){
//当图片宽度大于控件宽度 设置居中对齐
Log.d("gac","图片宽度大于控件宽度"+" "+rect.top+" "+rect.bottom+" "+rect.left+" "+rect.right);
canvas.drawBitmap(mImg,null,rect,mPaint);
}
}
}