自定义控件Image View的实现

设置自定义控件所需属性,此设定可用于xml布局,在布局文件layout中设置绘制控件所需的color,paintwidth等。在res->values下的attrs文件加入所需属性:

 <!--MyImageView属性定义-->
    <attr name="borderRadius" format="dimension"></attr>
    <attr name="imageType">
        <enum name="circle" value="0"></enum>
        <enum name="round" value="1"></enum>
    </attr>
    <declare-styleable name="MyImageView">
        <attr name="borderRadius"></attr>
        <attr name="imageType"></attr>
        <attr name="weight" format="integer"></attr>
        <attr name="hadFrame" format="boolean"></attr>
    </declare-styleable>

declare-styleable中的name为layout中使用的控件name,attr中指定属性名及所属类型,layout文件使用如下:

<cn.cjwddz.knowu.view.MyImageView
            android:id="@+id/myImageView"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:layout_gravity="center"
            android:scaleType="fitCenter"
            android:src="@drawable/dfheader"
            app:borderRadius="20dp"
            app:imageType="circle"
            app:weight="5"
            >
        </cn.cjwddz.knowu.view.MyImageView>

二,创建MyImageView的类,extends原生的Image View。实现init方法,初始化各类属性及获取自定义属性值

private void init(Context context, @Nullable AttributeSet attrs, int defStyleAttr){
        //初始化各属性
        matrix = new Matrix();
        matrix1 = new Matrix();
        paint = new Paint();
        dPaint = new Paint();
        framePaint = new Paint();
        dPaint.setAntiAlias(true);
        dPaint.setStyle(Paint.Style.FILL);
        dPaint.setColor(Color.WHITE);
        paint.setAntiAlias(true);
        framePaint.setAntiAlias(true);

        //获取自定义属性值
        TypedArray array = context.getTheme().obtainStyledAttributes(attrs, R.styleable.MyImageView,defStyleAttr,0);
        int count = array.getIndexCount();
        for(int i=0;i<count;i++){
            int attr = array.getIndex(i);
            switch (attr){
                case R.styleable.MyImageView_borderRadius:
                    borderRadius = array.getDimensionPixelSize(R.styleable.MyImageView_borderRadius,(int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, BORDER_RADIUS_DEFAULT, getResources().getDisplayMetrics()));
                    break;
                case R.styleable.MyImageView_imageType:
                    type = array.getInt(R.styleable.MyImageView_imageType,TYPE_CIRCLE);
                    break;
                case R.styleable.MyImageView_weight:
                    weights = array.getInt(R.styleable.MyImageView_weight,WEIGHT);
                    break;
                case R.styleable.MyImageView_hadFrame:
                    hadFrame = array.getBoolean(R.styleable.MyImageView_hadFrame,hadFrame);
                default:break;
            }
        }
        array.recycle();
    }

通过下列代码获取attr数组

 TypedArray array = context.getTheme().obtainStyledAttributes(attrs, R.styleable.MyImageView,defStyleAttr,0);

并获取特定的属性值,第一个元素为attrs文件所对应id,第二个元素为默认值。

 type = array.getInt(R.styleable.MyImageView_imageType,TYPE_CIRCLE);

最后记得( array.recycle();)回收TypedArray array释放内存。

三,重写onMeasure方法(设定view的大小)【可不重写】。

 @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        if(type == TYPE_CIRCLE){
            //获取父布局的最小值作为ImageView的宽高
            width = Math.min(getMeasuredWidth(),getMeasuredHeight());
            //设置圆形圆心点坐标
            point = width/weights;
            //设置圆半径
            radius = width/weights;
            //设置当前ImageView控件的宽高
            setMeasuredDimension(width/weights*2,width/weights*2);
        }
        if(type == TYPE_ROUND){
            width = Math.min(getMeasuredWidth(),getMeasuredHeight());
            setMeasuredDimension(width/2,width/2);
        }
    }

四,重写onDraw方法,绘制自定义控件内容。

  @Override
    protected void onDraw(Canvas canvas) {
        if(getDrawable() ==null){
            if(type == TYPE_CIRCLE){
                //在ImageView上无图画圆
                canvas.drawCircle(point,point,radius,dPaint);
                if(hadFrame){
                    canvas.drawCircle(point,point,radius,framePaint);
                }
            }else{
                //在ImageView上无图画圆角矩形
                canvas.drawRoundRect(rect,borderRadius,borderRadius,dPaint);
            }
        }else{
            setShader();
            if(type == TYPE_CIRCLE){
                //在ImageView上以位图渲染画圆
                canvas.drawCircle(point,point,radius,paint);
                if(hadFrame){
                    canvas.drawCircle(point,point,radius,framePaint);
                }
            }else{
                //在ImageView上以位图渲染画圆角矩形
                canvas.drawRoundRect(rect,borderRadius,borderRadius,paint);
            }
        }

    }

设置渲染

 private void setShader(){
        Drawable drawable = getDrawable();
        if (drawable == null) {
            return;
        }
        //将drawable转换成bitmap
        Bitmap bitmap = drawable2Bitmap(drawable);

        //CLAMP(拉伸)、REPEAT(重复)、MIRROR(镜像),shader的拉伸方式为拉伸最后一像素
        bitmapShader = new BitmapShader(bitmap, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP);

        //图片缩放,若图片仍小于ImageView则拉伸最后一像素,否则不拉伸
        float scale = 1.0f;
        float scale1 ;

        if(type == TYPE_CIRCLE){
            // bitmap.getxxx获取位图的宽高,getxxx获取ImageView的宽高取小值,如果取大值的话,则不能覆盖view
            int bitmapWidth = Math.min(bitmap.getWidth(),getHeight());
            scale = getWidth()*1.0f/bitmapWidth;//scale=2.0
        }else if(type ==TYPE_ROUND){
            scale = Math.max(getWidth()*1.0f/bitmap.getWidth(),getHeight()*1.0f/bitmap.getHeight());//scale=2.0
        }
        matrix.setScale(scale,scale);
        bitmapShader.setLocalMatrix(matrix);
        paint.setShader(bitmapShader);
        if(hadFrame){
            Drawable drawable1 = getResources().getDrawable(R.drawable.headframe,null);
            Bitmap bitmap1 = drawable2Bitmap(drawable1);
            bitmapShader1 = new BitmapShader(bitmap1, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP);
            int bitmapWidth1 = Math.min(bitmap1.getWidth(),bitmap1.getHeight());
            scale1 = getWidth()*1.0f/bitmapWidth1;
            matrix1.setScale(scale1,scale1);
            bitmapShader1.setLocalMatrix(matrix1);
            framePaint.setShader(bitmapShader1);
        }
    }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值