android 自定义View

91 阅读2分钟

学习鸿洋大神的同时记录下自己不熟悉的方法

1.创建1个自定义的VIEW

1.1.0:VIEW中包含图片以及文字

1.1.1:图片能够以填充和居中的模式体现

1.1.2:文字能够在超出长度时省略

1.不熟悉的方法

//相当于xml 中的ellipsize 根据长度进行截取
TextUtils.ellipsize() 
//第一个参数为要绘制的bitmap对象,
//第二个参数为要绘制的Bitmap对象的矩形区域,
//第三个参数为要将bitmap绘制在屏幕的什么地方,
//第四个参数为Paint对象。
canvas.drawBitmap(mImage,null,rect,mPaint);

//match_parent/accurate
MeasureSpec.EXACLY
//wrap_content
MeasureSpec.AT_MOST

//图片工厂.解析资源(获取资源——》获取的哪个资源)
mImage = BitmapFactory.decodeResource(getResources(), 
a.getResourceId(R.styleable.customViewStyle_image, 0));

//文字切割,String,文字画笔,长度,超过第3个长度的字符将会被转化成...
String msg = TextUtils.ellipsize(mTitle, textPaint
, mWidth - getPaddingLeft() - getPaddingRight(),TextUtils.TruncateAt.END).toString();



public class CustomView extends View {
    private int mTitleSize;
    private String mTitle;
    private Bitmap mImage;
    private int mTextColor;
    private int mImageScale;

    private int mWidth;
    private int mHeight;

    private Paint mPaint;
    private Rect mBound;
    private Rect rect;

    private float strokeWidth;

    private final int IMAGE_SCALE_FILL = 0;
    private final int IMAGE_SCALE_CENTER = 1;

    public CustomView(Context context) {
        this(context,null);//这边是this
    }

    public CustomView(Context context, @Nullable AttributeSet attrs) {
        this(context, attrs,0);//这边是this
    }

    public CustomView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        TypedArray a = context.obtainStyledAttributes(attrs,R.styleable.customViewStyle,defStyleAttr,0);
        mTextColor = a.getColor(R.styleable.customViewStyle_titleColor, Color.BLACK);
        mTitle = a.getString(R.styleable.customViewStyle_titleText);
        mTitleSize = a.getDimensionPixelSize(R.styleable.customViewStyle_titleSize,
                (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP,16,getResources().getDisplayMetrics()));
        mImageScale = a.getInt(R.styleable.customViewStyle_imageScaleType,0);
        //图片工程.解析资源(总资源中,获取指定的图片资源)
        mImage = BitmapFactory.decodeResource(getResources(),a.getResourceId(R.styleable.customViewStyle_image,0));
        
        a.recycle();

        mPaint = new Paint();
        mBound = new Rect();
        mPaint.setTextSize(mTitleSize);
        mPaint.getTextBounds(mTitle,0,mTitle.length(),mBound);
        rect = new Rect();
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        int specMode = MeasureSpec.getMode(widthMeasureSpec);
        int specSize = MeasureSpec.getSize(widthMeasureSpec);
        if(specMode == MeasureSpec.EXACTLY){//match_parent,accurate(精确的)
            mWidth =specSize ;
        }else{
            int desireByImage = getPaddingLeft()+getPaddingRight()+mImage.getWidth();
            int desireByTitle = getPaddingLeft()+getPaddingRight()+mBound.width();
            if(specMode == MeasureSpec.AT_MOST){//wrap_content
                //取最大保证能完全显示
                int desire = Math.max(desireByImage,desireByTitle);
                //取最小保证最小的边框距离
                mWidth = Math.min(desire,specSize);

            }
        }
        specMode = MeasureSpec.getMode(heightMeasureSpec);
        specSize = MeasureSpec.getSize(heightMeasureSpec);
        if(specMode == MeasureSpec.EXACTLY){
            mHeight = specSize;
        }else{
            //图片在上,文字在下
            int desire = getPaddingTop()+getPaddingBottom()+mImage.getHeight()+mBound.height();
            if(specMode == MeasureSpec.AT_MOST){
                mHeight = Math.min(specSize,desire);
            }
        }
        setMeasuredDimension(mWidth,mHeight);
    }

    @Override
    protected void onDraw(Canvas canvas) {

//        mPaint = new Paint();
//        mBound = new Rect()
//        mPaint.setTextSize(mTitleSize);
//        mPaint.getTextBounds(mTitle,0,mTitle.length(),mBound);
//        rect = new Rect();


        mPaint.setStrokeWidth(4);//边框宽度
        mPaint.setStyle(Paint.Style.STROKE);//类型边框
        mPaint.setColor(Color.CYAN);//颜色
        strokeWidth = mPaint.getStrokeWidth();
        canvas.drawRect(0, 0, getMeasuredWidth(), getMeasuredHeight(), mPaint);//画布画底色

        //除去padding的一个框,将在框中完成画笔制作
        rect.left = getPaddingLeft();
        rect.right = mWidth - getPaddingRight();
        rect.top = getPaddingTop();
        rect.bottom = mHeight - getPaddingBottom();


        mPaint.setColor(mTextColor);
        mPaint.setStyle(Paint.Style.FILL);
        /**
         * 2种情况
         * 1.accurate(精确)模式下,字体大于图片大于固定尺寸显示不全
         * 2.wrap_content 模式下,就不需要对面按照测量尺寸走
         */
        if(mBound.width() > mWidth){
            //文本画笔
            TextPaint textPaint = new TextPaint(mPaint);
            //文字切割,String,文字画笔,长度,超过第3个长度的字符将会被转化成...
            String msg = TextUtils.ellipsize(mTitle,textPaint,mWidth-getPaddingLeft()-getPaddingRight(),
                    TextUtils.TruncateAt.END ).toString();
            canvas.drawText(msg,getPaddingLeft(),mHeight-getPaddingBottom()-strokeWidth,mPaint);
        }else{
            canvas.drawText(mTitle,mWidth/2-mBound.width()*1.0f/2,mHeight-getPaddingBottom()-strokeWidth,mPaint);
        }

        //图片的底线
        rect.bottom = rect.bottom - mBound.height()-getPaddingBottom();
        if(mImageScale == IMAGE_SCALE_FILL){
            //第一个参数为要绘制的bitmap对象,第二个参数为要绘制的Bitmap对象的矩形区域,第三个参数为要将bitmap绘制在屏幕的什么地方,第四个参数为Paint对象。
            canvas.drawBitmap(mImage,null,rect,mPaint);

        }else{
            rect.left = getWidth()/2-mImage.getWidth()/2+getPaddingLeft();
            rect.right = getWidth()/2+mImage.getWidth()/2-getPaddingRight();
            rect.top = (getHeight()- mBound.height())/2-mImage.getHeight()/2+getPaddingTop();
            rect.bottom = (getHeight() - mBound.height())/2+mImage.getHeight()/2-getPaddingBottom();

            canvas.drawBitmap(mImage,null,rect,mPaint);
        }

    }
}