一、主要步骤
①、创建MyImageView类,并继承View
②、设置View控件的xml属性,也就是attr
③、在layout中配置View
④、获取View控件的属性,然后获取图片,并显示。
⑤、设定ImageView的大小
二、制作:
1、首先继承View类
public class MyImageView extends View{
public MyImageView(Context context) {
this(context,null);//将super(context)改成这种方式,下面依次类推
}
public MyImageView(Context context, AttributeSet attrs) {
this(context,attrs,0);
}
public MyImageView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
}
知识点①:利用this()方便操作。
2、设置View的属性
在layout/values下创建attr_image.xml
<declare-styleable name="MyImageView">
<!--仿造ImageView,所以将名字设成src-->
<!--由于图片肯定是从资源文件中,获取id的形式,所以选择reference:表示接受引用资源的id-->
<attr name="src" format="reference"/>
</declare-styleable>
知识点②:format="reference" 的意思是 接收引用资源的id
3、在layout中添加View
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.cgx.usecustomview.MainActivity">
<com.cgx.usecustomview.MyImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content<span style="font-family: Arial, Helvetica, sans-serif;">"</span>
app:src="@mipmap/ic_launcher"/>
</RelativeLayout>
public MyImageView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
initWidget(context,attrs);
}
private void initWidget(Context context,AttributeSet attrs){
//创建画笔,设置抗锯齿效果
mPhotoPaint = new Paint();
mPhotoPaint.setAntiAlias(true);
if (attrs != null){
TypedArray a = context.obtainStyledAttributes(attrs,R.styleable.MyImageView);
//知识点:图片类型,只能用drawable接受
mPhotoDrawable = a.getDrawable(R.styleable.MyImageView_src);
}
}
知识点③:图片类型,只能用Drawable接口,无法直接使用Bitmap接收。
将Drawable图片转换为Bitmap,并显示图片
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
if (mPhotoDrawable != null){
Bitmap bitmap = drawableToBitmap();
canvas.drawBitmap(bitmap,0,0,mPhotoPaint);
}
}
//drawable转换成bitmap
private Bitmap drawableToBitmap(){
//创建一个Bitmap缓冲区
Bitmap bitmap = Bitmap.createBitmap(mPhotoDrawable.getIntrinsicWidth(),mPhotoDrawable.getIntrinsicHeight(),mPhotoDrawable.getOpacity() != PixelFormat.OPAQUE ? Bitmap.Config.ARGB_8888 : Bitmap.Config.RGB_565);
//将这个缓冲区设置成画板
Canvas canvas = new Canvas(bitmap);
//设定drawable将绘制在Canvas的哪个位置
mPhotoDrawable.setBounds(0,0,mPhotoDrawable.getIntrinsicWidth(),mPhotoDrawable.getIntrinsicHeight());
//将drawable图案绘制在bitmap中
mPhotoDrawable.draw(canvas);
return bitmap;
}
知识点④:如何将Drawable转换成Bitmap。
该知识点可用于Drawable中的双缓冲机制。双缓冲机制也是先将图画在内存的缓冲区中,然后再将缓冲区中的数据转换成Bitmap之后再显示。
5、设置ImageView的大小问题。(让MyImageView兼容wrap_content)
这样设置的View,如果设置了wrap_content其实还是match_parent的状态
//重写了View的onMeasure()方法
//mPhotoWidth = drawble.getIntrinsicWidth();
//mPhotoHeight = drawble.getIntrinsicHeight()
//由于使用次数频繁,所以选择复用
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
int widthSpecSize = MeasureSpec.getSize(widthMeasureSpec);
int widthSpecMode = MeasureSpec.getMode(widthMeasureSpec);
int heightSpecSize = MeasureSpec.getSize(heightMeasureSpec);
int heightSpecMode = MeasureSpec.getMode(heightMeasureSpec);
if (widthSpecMode == MeasureSpec.AT_MOST && heightSpecMode == MeasureSpec.AT_MOST){
setMeasuredDimension(mPhotoWidth,mPhotoHeight);
}
else if (widthMeasureSpec == MeasureSpec.AT_MOST){
setMeasuredDimension(mPhotoWidth,heightSpecSize);
}
else if (heightMeasureSpec == MeasureSpec.AT_MOST){
setMeasuredDimension(widthSpecSize,mPhotoHeight);
}
else {
setMeasuredDimension(widthSpecSize,heightSpecSize);
}
}
基本的操作就是这样。
要完成一个完整的ImageView的话,还需要scaleType属性~~~。