自定义ImageView

属性文件:
<?xml version="1.0" encoding="utf-8"?>
<resources>
    <attr name="titleText" format="string"></attr>
    <attr name="titleTextSize" format="dimension"></attr>
    <attr name="textColor" format="color"></attr>
    <attr name="image" format="reference"></attr>
    <attr name="imageScaleType" >
        <enum name="fillXY" value="0"></enum>
        <enum name="center" value="1"></enum>
    </attr>
    <declare-styleable name="CustomImageView">
        <attr name="titleText"/>
        <attr name="titleTextSize"/>
        <attr name="textColor"/>
        <attr name="image"/>
        <attr name="imageScaleType"/>
    </declare-styleable>
</resources>


实现类:
public class CustomImageView extends ImageView {
    private Bitmap mImg;
    private String mText;
    private int mColor;
    private int mSize;
    private Rect mBound;//绘制文本的范围
    private Paint mPaint;
    private int mImgScale;//0 fill填充 1 居中对齐

    private Rect rect; //图片范围
    private int width;
    private int height;
    public CustomImageView(Context context) {
        this(context,null);
    }

    public CustomImageView(Context context, AttributeSet attrs) {
       this(context,attrs,0);
    }

    public CustomImageView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        TypedArray ta = context.getTheme().obtainStyledAttributes(attrs,R.styleable.CustomImageView,defStyleAttr,0);
        int n  = ta.getIndexCount();
        for(int i = 0; i < n; i++){
            int attr = ta.getIndex(i);
            switch (attr){
                case R.styleable.CustomImageView_image:
                    mImg = BitmapFactory.decodeResource(getResources(),ta.getResourceId(attr,0));
                    break;
                case R.styleable.CustomImageView_imageScaleType:
                    mImgScale = ta.getInt(attr,0);
                    break;
                case R.styleable.CustomImageView_titleText:
                    mText = ta.getString(attr);
                     break;
                case R.styleable.CustomImageView_textColor:
                    mColor = ta.getColor(attr, Color.BLACK);
                    break;
                case R.styleable.CustomImageView_titleTextSize:
                    mSize = ta.getDimensionPixelSize(attr,(int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP,16,getResources().getDisplayMetrics()));
                    break;
            }
        }
        ta.recycle();
        rect = new Rect();
        mPaint = new Paint();
        mBound = new Rect();
        mPaint.setTextSize(mSize);
        mPaint.getTextBounds(mText, 0, mText.length(),mBound);

    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        //super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        //设置宽度
        /*
        * 当设置为wrap_content
        * 取宽度为图片 和字体的宽度的最大值
        * 这个值不能大于 父控件给定的值 取和父控件的最小值
        * 当文本宽度大于图片长度 大于控件长度 就会显示xx....
        * 当图片宽度大于文本长度小于控件长度显示
        * //当图片宽度大于文本长度 大于控件长度应该剪裁图片
        * */
        int specMode = MeasureSpec.getMode(widthMeasureSpec);
        int specSize = MeasureSpec.getSize(widthMeasureSpec);//父布局给的宽度
        if(specMode == MeasureSpec.EXACTLY){//match_parent,accurate 精确值
            //固定宽度 高度 specSize 为3倍的固定宽高 不知道为什么?
            width = specSize;
            Log.d("gac","img width"+mImg.getWidth());
            Log.d("gac","specSizeWidth:"+specSize);


        }else{
            //由图片决定宽度
            int desiredImg = getPaddingLeft()+getPaddingRight()+mImg.getWidth();
            //由字体决定的宽度
            int desiredText = getPaddingLeft()+getPaddingRight()+mBound.width();
            if(specMode == MeasureSpec.AT_MOST){//wrap_content
                int desire = Math.max(desiredImg,desiredText);
                width = Math.min(desire,specSize);
                /*MeasureSpec.AT_MOST模式表示你的宽度不能超过父控件给定的值即specSize
                * */
            }else{
                width = specSize;
                Log.d("gac","specSizeWidth:"+specSize);
            }
        }

        //设置高度
        specMode = MeasureSpec.getMode(heightMeasureSpec);
        specSize = MeasureSpec.getSize(heightMeasureSpec);
        if(specMode == MeasureSpec.EXACTLY){
            //固定宽度 高度 specSize 为3倍的固定宽高 不知道为什么?
            height = specSize;

            Log.d("gac","specSizeHeight:"+specSize);
        }else{
            int desire = getPaddingTop() + getPaddingBottom() + mImg.getHeight() + mBound.height();
            if (specMode == MeasureSpec.AT_MOST)// wrap_content
            {
                height = Math.min(desire, specSize);
            }else{
                height = specSize;
                Log.d("gac","specSizeHeight:"+specSize);
            }
        }
        setMeasuredDimension(width,height);
    }

    @Override
    protected void onDraw(Canvas canvas) {
       // 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 = width - getPaddingRight();
        rect.top = getPaddingTop();
        rect.bottom = height - getPaddingBottom();
        mPaint.setColor(mColor);
        mPaint.setStyle(Paint.Style.FILL);

        /**
         * 当字体宽度大于控件宽度
         * 当前设置的宽度小于字体需要的宽度,将字体改为xxx...
         */
        if(mBound.width() > width){
            TextPaint paint = new TextPaint(mPaint);
            String msg = TextUtils.ellipsize(mText,paint,(float)width - getPaddingLeft()-getPaddingRight(),TextUtils.TruncateAt.END).toString();
            canvas.drawText(msg,getPaddingLeft(),height - getPaddingBottom(),mPaint);
        }else{
            //正常情况字体居中
            canvas.drawText(mText,width/2-mBound.width()*1.0f/2,height - getPaddingBottom(),mPaint);
        }
        /*
        * 当图片宽度大于控件宽度应该剪裁图片
        * */
        //取消使用掉的块  图片不要画到下面的文字
        rect.bottom -=mBound.height();
        if(mImgScale == 0){//fillxy
            canvas.drawBitmap(mImg,null,rect,mPaint);
        }else if(mImgScale == 1 && width > mImg.getWidth()) {

            //计算居中的矩形范围
           Log.d("gac","imgwidth" +mImg.getWidth() +" width"+width);
            rect.left = width / 2 - mImg.getWidth() / 2;//图片左上角x坐标  (width-mImgWidth)/2
            rect.right = width / 2 + mImg.getWidth() / 2;//图片右上角x坐标 (width-mImgWidth)/2+mImgWidth
            rect.top = (height - mBound.height()) / 2 - mImg.getHeight() / 2;//图片顶部坐标 y轴坐标 (总高度- 字体高度-图片高度)/2
            rect.bottom = (height - mBound.height()) / 2 + mImg.getHeight() / 2;//图片底部y坐标 (总高度-字体高度-图片高度)/2+图片高度

            canvas.drawBitmap(mImg, null, rect, mPaint);

        }else if(mImgScale == 1 && (mImg.getWidth() > width)){
            //当图片宽度大于控件宽度 设置居中对齐
            Log.d("gac","图片宽度大于控件宽度"+" "+rect.top+" "+rect.bottom+" "+rect.left+" "+rect.right);
            canvas.drawBitmap(mImg,null,rect,mPaint);
        }
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值