自定义类似ImageView的控件

一、主要步骤

①、创建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>


4、在代码中,获取图片
  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属性~~~。



  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值