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<n;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="https://schemas.android.com/apk/res/com.zhy.customview02"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<com.zhy.customview02.view.customimageview
android:layout_margin="10dp"
android:padding="10dp"
zhy:image="@drawable/ic_launcher"
zhy:imageScaleType="center"
zhy:titleText="helloandorid!"
zhy:titleTextColor="#ff0000"
zhy:titleTextSize="30sp"/>
<com.zhy.customview02.view.customimageview
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"/>
<com.zhy.customview02.view.customimageview
android:layout_margin="10dp"
android:padding="10dp"
zhy:image="@drawable/lmj"
zhy:imageScaleType="center"
zhy:titleText="妹子~"
zhy:titleTextColor="#ff0000"
zhy:titleTextSize="12sp"/>