很多人对自定义view都很胆怯,其实自己去玩一玩会发现很简单。
#知识点
个人把自定义View分为以下四个步骤
####1、自定义View的属性
####2、在View的构造方法中获得我们自定义的属性
####3、重写onMesure
####4、重写onDraw
##简单的自定义View Demo
###1、自定义View的属性
<?xml version="1.0" encoding="utf-8"?>
<resources>
//??????,??????
<attr name="titleText" format="string"/>
<attr name="titleTextSize" format="dimension"/>
<attr name="titleTextColor" format="color"/>
<attr name="image" format="reference"/>
<attr name="imageScaleType" >
<enum name="fillXY" value="0"/>
<enum name="center" value="1"/>
</attr>
//??????????
<declare-styleable name="CustomImageView">
<attr name="titleText" />
<attr name="titleTextSize" />
<attr name="titleTextColor" />
<attr name="image" />
<attr name="imageScaleType" />
</declare-styleable>
</resources>
###2、在View的构造方法中获得我们自定义的属性
public class CustomImageView extends View {
private static final String TAG = CustomImageView.class.getSimpleName();
/**
* ????
*/
private int mWidth;
/**
* ????
*/
private int mHeight;
/**
* ??????
*/
private Bitmap mImage;
/**
* ???????
*/
private int mImageScale;
private static final int IMAGE_SCALE_FITXY = 0;
private static final int IMAGE_SCALE_CENTER = 1;
/**
* ?????
*/
private String mTitle;
/**
* ?????
*/
private int mTextColor;
/**
* ?????
*/
private int mTextSize;
private Paint mPaint;
/**
* ??????
*/
private Rect mTextBound;
/**
* ??????
*/
private Rect rect;
public CustomImageView(Context context) {
super(context);
}
public CustomImageView(Context context, @Nullable AttributeSet attrs) {
this(context,attrs,0);
}
public CustomImageView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
TypedArray typedArray = context.getTheme().obtainStyledAttributes(attrs, R.styleable.CustomImageView, defStyleAttr, 0);
int indexCount = typedArray.getIndexCount();
for (int i = 0; i < indexCount; i++) {
int attr = typedArray.getIndex(i);
switch (attr) {
case R.styleable.CustomImageView_image:
mImage = BitmapFactory.decodeResource(getResources(), typedArray.getResourceId(attr, 0));
break;
case R.styleable.CustomImageView_imageScaleType:
mImageScale = typedArray.getInt(attr, 0);
break;
case R.styleable.CustomImageView_titleText:
mTitle = typedArray.getString(attr);
break;
case R.styleable.CustomImageView_titleTextColor:
mTextColor = typedArray.getColor(attr, Color.BLACK);
break;
case R.styleable.CustomImageView_titleTextSize:
mTextSize = typedArray.getDimensionPixelSize(attr, (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP,16,getResources().getDisplayMetrics()));
break;
}
}
typedArray.recycle();
rect = new Rect();
mPaint = new Paint();
mTextBound = new Rect();
mPaint.setTextSize(mTextSize);
//???????????
mPaint.getTextBounds(mTitle,0,mTitle.length(),mTextBound);
}
}
###3、重写onMesure
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
//super.onMeasure(widthMeasureSpec, heightMeasureSpec);
// TODO: 2017/3/22
/**
* UNSPECIFIED ????????????,????????
* EXACTLY ?????????,???????????,??????????
* AT_MOST ????????????
*/
//????
int specMode = MeasureSpec.getMode(widthMeasureSpec);
int specSize = MeasureSpec.getSize(widthMeasureSpec);
if(specMode == MeasureSpec.EXACTLY){ //match_parent
Logger.i("EXACTLY");
mWidth = specSize;
}else {
//??????
int desireByImg = getPaddingLeft() + getPaddingRight() + mImage.getWidth();
//??????
int desireByTitle = getPaddingLeft() + getPaddingRight() + mTextBound.width();
if(specMode == MeasureSpec.AT_MOST){ //wrap_content
int desire = Math.max(desireByImg,desireByTitle);
mWidth = Math.min(desire,specSize);
Logger.i("AT_MOST");
}
Logger.i("getPaddingLeft "+getPaddingLeft() + " getPaddingRight()"+ getPaddingRight());
}
//????
specMode = MeasureSpec.getMode(heightMeasureSpec);
specSize = MeasureSpec.getSize(heightMeasureSpec);
if(specMode == MeasureSpec.EXACTLY){ //macth_parent
mHeight = specSize;
}else{
int desire = getPaddingTop()+getPaddingBottom()+mImage.getHeight()+mTextBound.height();
if(specMode == MeasureSpec.AT_MOST){ //wrap_content
mHeight = Math.min(desire,specSize);
}
}
setMeasuredDimension(mWidth,mHeight);
}
###4、重写onDraw
@Override
protected void onDraw(Canvas canvas) {
//super.onDraw(canvas);
/**
* ??
*/
mPaint.setStrokeWidth(4);
mPaint.setStyle(STROKE); // STROKE ?? FILL??
mPaint.setColor(Color.CYAN);
canvas.drawRect(0,0,getMeasuredWidth(),getMeasuredHeight(),mPaint);
// TODO: 2017/3/22
rect.left = getPaddingLeft();
rect.right = mWidth - getPaddingRight();
rect.top = getPaddingTop();
rect.bottom = mHeight - getPaddingBottom();
mPaint.setColor(mTextColor);
mPaint.setStyle(Paint.Style.FILL);
/**
* ????????????????,?????xxx...
*/
if(mTextBound.width() > mWidth){
TextPaint textpaint = new TextPaint(mPaint);
String msg = TextUtils.ellipsize(mTitle,textpaint,(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);
}
// TODO: 2017/3/22
//???????
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;
Logger.e("mWidth : " +mWidth + " mImage.getWidth() : " +mImage.getWidth());
canvas.drawBitmap(mImage, null, rect, mPaint);
}
}
就是这么简单 完成了自定义View 接下来让我们看看如何使用
##应用
在布局使用的时候先要定义一下如下信息
xmlns:app="http://schemas.android.com/apk/res-auto"
然后才能使用
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 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"
android:orientation="vertical">
<com.libin.factory.widget.CustomImageView
android:id="@+id/civ_1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="10dp"
android:padding="10dp"
app:image="@drawable/bg_test"
app:imageScaleType="center"
app:titleText="hello andorid ! "
app:titleTextColor="#ff0000"
app:titleTextSize="30sp" />
</LinearLayout>
???
工程地址:
https://github.com/libin7278/Factory
java --》widget
扫码关注公众号“伟大程序猿的诞生“,更多干货新鲜文章等着你~
公众号回复“资料获取”,获取更多干货哦~
有问题添加本人微信号“fenghuokeji996” 或扫描博客导航栏本人二维码