安卓复习之旅—自定义view(一)

来源:互联网 发布:淘宝中药模板 编辑:程序博客网 时间:2024/05/16 12:32

今天开始复习一下自定义view相关的知识。
先上图看看效果吧:
这里写图片描述
额 好像奥运五环那几个字没有居中。。。先这样吧(嘿嘿)开始coding吧:
step1定义需要自定义的属性
在res/values/文件夹创建一个attrs.xml文件,在里面编辑需要的自定义属性

<?xml version="1.0" encoding="utf-8"?><resources>    <attr name="textColor" format="color" />    <attr name="textSize" format="dimension" />    <declare-styleable name="FiveCricle">        <attr name="textColor" />        <attr name="textSize" />    </declare-styleable></resources>

step2代码中定义需要的属性

// 圆环的画笔    private Paint bluePain;    private Paint greenPain;    private Paint redPain;    private Paint blackPain;    private Paint yelloPain;    //文本画笔    private Paint textPain;    // 画布的宽高    private int mCanvasWidth, mCanvasHeight;    // 圆的半径    private int mRadius = 80;    // 1. 自定义的一些属性并赋值    /**     * 文本的颜色     */    private int mTextColor = 0xff00ff00;    /**     * 文本的大小     */    private int mTextSize = 10;

step3构造方法中初始化画笔和自定义属性
先来看看构造方法:在View类中有四个构造函数,涉及到多个参数, Context:上下文, AttributeSet attrs: 从xml中定义的参数,
int defStyleAttr :当前Theme中的包含的一个指向style的引用.当我们没有给自定义View设置declare-styleable资源集合时,默认从这个集合里面查找布局文件中配置属性值.传入0表示不向该defStyleAttr中查找默认值. ,int defStyleRes : 指向Style的资源,仅在defStyleAttr为0或者defStyleAttr不为0但Theme中没有为defStyleAttr属性赋值时起作用.
这里我们重写前两个参数;

// 在代码中直接new一个Custom View实例的时候,会调用第一个构造函数.    public FiveCricle(Context context) {        super(context);        // TODO Auto-generated constructor stub        initPain();    }    // 在xml布局文件中调用自定义属性的时候,会调用第二个构造函数.    public FiveCricle(Context context, AttributeSet attrs) {        super(context, attrs);        // TODO Auto-generated constructor stub        /**         * 获取自定义属性并设置初始值         */        TypedArray ta = context.obtainStyledAttributes(attrs, R.styleable.FiveCricle);        int n = ta.getIndexCount();        for (int i = 0; i < n; i++) {            int attr = ta.getIndex(i);            switch (attr) {            case R.styleable.FiveCricle_textColor:                mTextColor = ta.getColor(attr, mTextColor);                break;            case R.styleable.FiveCricle_textSize:                mTextSize = ta.getDimensionPixelOffset(attr, mTextSize);                break;            }        }        //记得回收哦        ta.recycle();        initPain();    }

初始化画笔

这里写代码片
bluePain = new Paint();        bluePain.setColor(0xff00ff00);        bluePain.setAntiAlias(true);        bluePain.setStyle(Paint.Style.STROKE);        bluePain.setStrokeWidth(10f);
    // 绘制文字的画笔        textPain = new Paint();        textPain.setAntiAlias(true);        textPain.setStyle(Paint.Style.FILL);

自定义view的流程先计算onMeasure()方法—>onLayout()—>
onDraw()
step4重写onmeasure方法
一个MeasureSpec封装了父布局传递给子布局的布局要求,每个MeasureSpec代表了一组宽度和高度的要求。 一个MeasureSpec由大小和模式组成。它有三种模式:UNSPECIFIED(未指定), 父元素部队自元素施加任何束缚,子元素可以得到任意想要的大小;EXACTLY(完全), 父元素决定自元素的确切大小, 子元素将被限定在给定的边界里而忽略它本身大小; AT_MOST(至多),子元素至多达到指定大小的值。

// 根据提供的测量值(格式)提取模式(上述三个模式之一)        int widthSize = MeasureSpec.getSize(widthMeasureSpec);        int widthMode = MeasureSpec.getMode(widthMeasureSpec);        int heightSize = MeasureSpec.getSize(heightMeasureSpec);        int heightMode = MeasureSpec.getMode(heightMeasureSpec);        int desiredWidth, desiredHeight;        if (widthMode == MeasureSpec.EXACTLY) {//确切的值或者match            desiredWidth = widthSize;        } else {            desiredWidth = mRadius * 2 * 4 + getPaddingLeft() + getPaddingRight();            if (widthMode == MeasureSpec.AT_MOST) {//wrap                desiredWidth = Math.min(widthSize, desiredWidth);            }        }        if (heightMode == MeasureSpec.EXACTLY) {            desiredHeight = heightSize;        } else {            desiredHeight = mRadius * 2 * 3 + getPaddingTop() + getPaddingBottom();            if (heightMode == MeasureSpec.AT_MOST) {                desiredHeight = Math.min(heightSize, desiredHeight);            }        }        setMeasuredDimension(mCanvasWidth = desiredWidth, mCanvasHeight = desiredHeight);

step5重写onDraw()

//设置画布的背景        mCanvas.drawColor(Color.WHITE);        // 将坐标系原点移至去除内边距后的画布中心        mCanvas.translate(mCanvasWidth * 1.0f / 2 + getPaddingLeft() - getPaddingRight(),                mCanvasHeight * 1.0f / 2 + getPaddingTop() - getPaddingBottom());        // 设置参数就可以将xml中的属性起作用        textPain.setColor(mTextColor);        textPain.setTextSize(mTextSize);        mCanvas.drawCircle(-180, 0, mRadius, redPain);        mCanvas.drawCircle(0, 0, mRadius, bluePain);        mCanvas.drawCircle(180, 0, mRadius, greenPain);        mCanvas.drawCircle(-90, 80, mRadius, yelloPain);        mCanvas.drawCircle(100, 80, mRadius, blackPain);        mCanvas.drawText("奥运五环", -80, -130, textPain);

step6最后编辑xml

<com.example.mycustomview.FiveCricle        android:layout_width="wrap_content"        android:layout_height="wrap_content"        custom:textColor="#0000ff"        custom:textSize="20sp" >    </com.example.mycustomview.FiveCricle>

okay,至此一个简单的自定义view就实现了
下载地址:http://download.csdn.net/my

0 0
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 月经量少且发黑怎么办 验孕试纸不加深怎么办 刚怀孕染了头发怎么办 2个月宝宝不吃奶怎么办 孕妇尿隐血1十是怎么办 尿葡萄糖2个加怎么办 孕妇尿葡萄糖2加怎么办 尿的蛋白高怎么办治疗 孕妇尿蛋白高是怎么办 孕妇尿细菌数高怎么办 孕妇尿细菌很高怎么办 尿微量总蛋白高怎么办 衣服上碳素笔油怎么办 卡油泵总成坏了怎么办 汽车燃油泵坏了怎么办 新车汽油泵坏了怎么办 墓地的树枯死了怎么办 大车尿素不烧了怎么办 不烧尿素限扭怎么办 汽车首保过期了怎么办 假体隆鼻后透光怎么办 熊猫血有抗体了怎么办 rh阴性血怀二胎怎么办 熊猫血怀二胎了怎么办 rh阴性血要二胎怎么办 全血粘度都偏高怎么办 血脂高血粘度高怎么办 全血粘度值1偏高怎么办 全血粘度3偏高怎么办 血粘度高的症状怎么办 粉瘤感染化脓了怎么办 乌药剂量用大了怎么办 水卡消磁了怎么办妙招 电卡消磁了怎么办妙招 入园磁卡消磁了怎么办 透析中静脉压高怎么办 腰间盘突出压迫神经腿疼怎么办 肺热引起的发烧怎么办 肺热引起的痘痘怎么办 冰箱压条的霉点怎么办 白色的布鞋变黄怎么办