自定义View笔记(一)

注:该笔记是整理学习鸿洋大神自定义View系列博客的部分知识点。

自定义View(自定义控件)四大步骤:

1. 自定义View的属性
2. 在View的构造方法中获取自定义的属性
3. 重写onMesure()   不是选项
4. 重写onDraw()

自定义View属性

/**    在res/values下建立一个attrs.xml文件    */
<resources>  

    <attr name="titleText" format="string" />  
    <attr name="titleTextSize" format="dimension" />  
    <attr name="titleTextColor" format="color" />  
    <attr name="image" format="reference" />  
    <attr name="imageScaleType">  
        <enum name="fillXY" value="0" />  
        <enum name="center" value="1" />  
    attr>  

    <declare-styleable name="CustomImageView">  
        <attr name="titleText" />  
        <attr name="titleTextSize" />  
        <attr name="titleTextColor" />  
        <attr name="image" />  
        <attr name="imageScaleType" />  
    declare-styleable>  

resources>  

注:format的取值类型有:
string — 字符串
color — 颜色值
demension — 尺寸值
integer — 整型值
float — 浮点值
reference — 参考某一资源ID
boolean — 布尔值
fraction — 百分数
enum — 枚举值
flag — 位或运算

获取自定义的样式属性

public CustomTitleView(Context context, AttributeSet attrs, int defStyle)  
    {  
        super(context, attrs, defStyle);  
        /** * 获得我们所定义的自定义样式属性 */  
        TypedArray a = context.getTheme().obtainStyledAttributes(attrs, R.styleable.CustomTitleView, defStyle, 0);  
        int n = a.getIndexCount();  
        for (int i = 0; i < n; i++)  
        {  
            int attr = a.getIndex(i);  
            switch (attr)  
            {  
            case R.styleable.CustomTitleView_titleText:  
                mTitleText = a.getString(attr);  
                break;  
            case R.styleable.CustomTitleView_titleTextColor:  
                // 默认颜色设置为黑色 
                mTitleTextColor = a.getColor(attr, Color.BLACK);      //参数:a.getColor(输入值, 默认值)
                break;  
            case R.styleable.CustomTitleView_titleTextSize:  
                // 默认设置为16sp,TypeValue也可以把sp转化为px 
                mTitleTextSize = a.getDimensionPixelSize(attr, (int) TypedValue.applyDimension(  
                        TypedValue.COMPLEX_UNIT_SP, 16, getResources().getDisplayMetrics()));  
                break;  

            }  

        }  
        a.recycle();  //将TypedArray回收

        /** * 获得绘制文本的宽和高 */  
        mPaint = new Paint();  
        mPaint.setTextSize(mTitleTextSize);  
        // mPaint.setColor(mTitleTextColor); 
        mBound = new Rect();  
        mPaint.getTextBounds(mTitleText, 0, mTitleText.length(), mBound);      //通过 getTextBound(String text,int start,int end,Rect bounds) 或者 getTextBound(char[] text,int index,int count,Rect bounds) 获取绘制的大小

    }  

重写onMeasure()

@Override  
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec)  
{  
    // super.onMeasure(widthMeasureSpec, heightMeasureSpec); 

    /** * 设置宽度 */  
    int specMode = MeasureSpec.getMode(widthMeasureSpec);  
    int specSize = MeasureSpec.getSize(widthMeasureSpec);  

    if (specMode == MeasureSpec.EXACTLY)// match_parent , accurate 
    {  
        mWidth = specSize;  
    } else{  
        // 由图片决定的宽 
        int desireByImg = getPaddingLeft() + getPaddingRight() + mImage.getWidth();  
        // 由字体决定的宽 
        int desireByTitle = getPaddingLeft() + getPaddingRight() + mTextBound.width();  

        if (specMode == MeasureSpec.AT_MOST)// wrap_content 
        {  
            int desire = Math.max(desireByImg, desireByTitle);     //取 desireByImg, desireByTitle中最大值
            mWidth = Math.min(desire, specSize);  
        }  
    }  

    /** * 设置高度 */  
    specMode = MeasureSpec.getMode(heightMeasureSpec);  
    specSize = MeasureSpec.getSize(heightMeasureSpec);  
    if (specMode == MeasureSpec.EXACTLY)// match_parent , accurate 
    {  
        mHeight = specSize;  
    } else {  
        int desire = getPaddingTop() + getPaddingBottom() + mImage.getHeight() + mTextBound.height();  
        if (specMode == MeasureSpec.AT_MOST)// wrap_content 
        {  
            mHeight = Math.min(desire, specSize);  
        }  
    }  
    setMeasuredDimension(mWidth, mHeight);  
}  

你可能感兴趣的:(android)