Android 自定义View (二) 进阶,继续自定义View之旅,前面已经介绍过一个自定义View的基础的例子,Android 自定义View (一),如果你还对自定义View不了解可以去看看。今天给大家带来一个稍微复杂点的例子。
自定义View显示一张图片,下面包含图片的文本介绍,类似相片介绍什么的,不过不重要,主要是学习自定义View的用法么。
还记得上一篇讲的4个步骤么:
1、自定义View的属性
2、在View的构造方法中获得我们自定义的属性
[ 3、重写onMesure ]
4、重写onDraw
直接切入正题:
1、在res/values/attr.xml
2、在构造中获得我们的自定义属性:
/**
*初始化所特有自定义类型
*
*@paramcontext
*@paramattrs
*@paramdefStyle
*/
publicCustomImageView(Contextcontext,AttributeSetattrs,intdefStyle)
{
super(context,attrs,defStyle);
TypedArraya=context.getTheme().obtainStyledAttributes(attrs,R.styleable.CustomImageView,defStyle,0);
intn=a.getIndexCount();
for(inti=0;i<>
{
intattr=a.getIndex(i);
switch(attr)
{
caseR.styleable.CustomImageView_image:
mImage=BitmapFactory.decodeResource(getResources(),a.getResourceId(attr,0));
break;
caseR.styleable.CustomImageView_imageScaleType:
mImageScale=a.getInt(attr,0);
break;
caseR.styleable.CustomImageView_titleText:
mTitle=a.getString(attr);
break;
caseR.styleable.CustomImageView_titleTextColor:
mTextColor=a.getColor(attr,Color.BLACK);
break;
caseR.styleable.CustomImageView_titleTextSize:
mTextSize=a.getDimensionPixelSize(attr,(int)TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP,
16,getResources().getDisplayMetrics()));
break;
}
}
a.recycle();
rect=newRect();
mPaint=newPaint();
mTextBound=newRect();
mPaint.setTextSize(mTextSize);
//计算了描绘字体需要的范围
mPaint.getTextBounds(mTitle,0,mTitle.length(),mTextBound);
}
3、重写onMeasure
@Override
protectedvoidonMeasure(intwidthMeasureSpec,intheightMeasureSpec)
{
//super.onMeasure(widthMeasureSpec,heightMeasureSpec);
/**
*设置宽度
*/
intspecMode=MeasureSpec.getMode(widthMeasureSpec);
intspecSize=MeasureSpec.getSize(widthMeasureSpec);
if(specMode==MeasureSpec.EXACTLY)//match_parent,accurate
{
Log.e("xxx","EXACTLY");
mWidth=specSize;
}else
{
//由图片决定的宽
intdesireByImg=getPaddingLeft()+getPaddingRight()+mImage.getWidth();
//由字体决定的宽
intdesireByTitle=getPaddingLeft()+getPaddingRight()+mTextBound.width();
if(specMode==MeasureSpec.AT_MOST)//wrap_content
{
intdesire=Math.max(desireByImg,desireByTitle);
mWidth=Math.min(desire,specSize);
Log.e("xxx","AT_MOST");
}
}
/***
*设置高度
*/
specMode=MeasureSpec.getMode(heightMeasureSpec);
specSize=MeasureSpec.getSize(heightMeasureSpec);
if(specMode==MeasureSpec.EXACTLY)//match_parent,accurate
{
mHeight=specSize;
}else
{
intdesire=getPaddingTop()+getPaddingBottom()+mImage.getHeight()+mTextBound.height();
if(specMode==MeasureSpec.AT_MOST)//wrap_content
{
mHeight=Math.min(desire,specSize);
}
}
setMeasuredDimension(mWidth,mHeight);
}
4、重写onDraw
@Override
protectedvoidonDraw(Canvascanvas)
{
//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=mWidth-getPaddingRight();
rect.top=getPaddingTop();
rect.bottom=mHeight-getPaddingBottom();
mPaint.setColor(mTextColor);
mPaint.setStyle(Style.FILL);
/**
*当前设置的宽度小于字体需要的宽度,将字体改为xxx...
*/
if(mTextBound.width()>mWidth)
{
TextPaintpaint=newTextPaint(mPaint);
Stringmsg=TextUtils.ellipsize(mTitle,paint,(float)mWidth-getPaddingLeft()-getPaddingRight(),
TextUtils.TruncateAt.END).toString();
canvas.drawText(msg,getPaddingLeft(),mHeight-getPaddingBottom(),mPaint);
}else
{
//正常情况,将字体居中
canvas.drawText(mTitle,mWidth/2-mTextBound.width()*1.0f/2,mHeight-getPaddingBottom(),mPaint);
}
//取消使用掉的快
rect.bottom-=mTextBound.height();
if(mImageScale==IMAGE_SCALE_FITXY)
{
canvas.drawBitmap(mImage,null,rect,mPaint);
}else
{
//计算居中的矩形范围
rect.left=mWidth/2-mImage.getWidth()/2;
rect.right=mWidth/2+mImage.getWidth()/2;
rect.top=(mHeight-mTextBound.height())/2-mImage.getHeight()/2;
rect.bottom=(mHeight-mTextBound.height())/2+mImage.getHeight()/2;
canvas.drawBitmap(mImage,null,rect,mPaint);
}
}
代码,结合注释和第一篇View的使用,应该可以看懂,不明白的留言。下面我们引入我们的自定义View:
xmlns:zhy="http://schemas.android.com/apk/res/com.zhy.customview02"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<> android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="10dp"
android:padding="10dp"
zhy:image="@drawable/ic_launcher"
zhy:imageScaleType="center"
zhy:titleText="helloandorid!"
zhy:titleTextColor="#ff0000"
zhy:titleTextSize="30sp"/>
<>
android:layout_width="100dp"
android:layout_height="wrap_content"
android:layout_margin="10dp"
android:padding="10dp"
zhy:image="@drawable/ic_launcher"
zhy:imageScaleType="center"
zhy:titleText="helloworldwelcome"
zhy:titleTextColor="#00ff00"
zhy:titleTextSize="20sp"/>
<> android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="10dp"
android:padding="10dp"
zhy:image="@drawable/lmj"
zhy:imageScaleType="center"
zhy:titleText="妹子~"
zhy:titleTextColor="#ff0000"
zhy:titleTextSize="12sp"/>