android开发自定义View(一)

在Android中控件一般分为两类View或者ViewGroup.
View的绘制过程大致有3步。

  1. 设置属性
  2. 测量
  3. 绘制

1.设置属性

在value下新建一个 attrs.xml 文件,用于设置文字的颜色,大小,内容。

<resources>
    <declare-styleable name="MyView">

        <attr name="textColor" format="color" />
        <attr name="textSize" format="dimension" />
        <attr name="textTitle" format="string" />

   </declare-styleable>
</resources>

在布局中可以这样设置

 <cn.jiangzehui.www.textview.MyView
        android:layout_width="200dp"
        android:layout_height="200dp"
        android:layout_centerHorizontal="true"
        android:layout_centerVertical="true"
        android:padding="5dp"
        zdy:textColor="#00ff00"
        zdy:textSize="20dp"
        zdy:textTitle="北京" />

设置的属性可以在构造方法中获取相应的值

public MyView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
       TypedArrayarray=context.getTheme().obtainStyledAttributes(attrs,R.styleable.MyView,defStyleAttr, 0);
        color = array.getColor(R.styleable.MyView_textColor, Color.BLACK);//获取颜色
        size = array.getDimensionPixelSize(R.styleable.MyView_textSize,(int)TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP, 20, getResources().getDisplayMetrics()));//获取文本大小
        title = array.getString(R.styleable.MyView_textTitle);//获取内容
        array.recycle();
        paint = new Paint();
        paint.setTextSize(size);
        paint.setAntiAlias(true);
        rect = new Rect();
        paint.getTextBounds(title, 0, title.length(), rect);
}

2.测量

View 提供了MeasureSpec类用于测量View的宽高。
测量分为3种方法。

  1. EXACTLY : 一般是设定了指定的大小或者match_parent.
  2. AT_MOST : 当View的大小设定为wrap_content时,我们需要给View设定一个最大值,默认是屏幕的宽高。
  3. UNSPECIFIED: 表示View的宽高可以无限大,几乎不会用到。

测量我们需要重写OnMeasure()方法。

  @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        //如果是WRAP_CONTENT时,我们需要自己进行测量,即重写onMesure方法
    setMeasuredDimension(measure_wh(widthMeasureSpec,0),measure_wh(heightMeasureSpec,1));
   }

/**
     * 测量宽度
     * @param measureSpec
     * @return
     */
    private int measure_wh(int measureSpec,int type) {
        int result = 0;
        int specMode = MeasureSpec.getMode(measureSpec);
        int specSize = MeasureSpec.getSize(measureSpec);
        if (specMode == MeasureSpec.EXACTLY) {
            result = specSize;
        } else {
            if(type==0){
                result = getPaddingLeft()+rect.width()+getPaddingRight();
            }else{
                result = getPaddingTop()+rect.width()+getPaddingBottom();
            }
        }

        if(type==0){
            viewWidth=result;
        }else{
            viewHeight=result;
        }


        return result;
    }

3.绘制

重写OnDraw()方法

 /**
     * 绘制
     * @param canvas
     */
    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);

        paint.setColor(Color.YELLOW);
        canvas.drawCircle(viewWidth/2,viewHeight/2,viewWidth/2,paint);
        paint.setColor(color);
        canvas.drawText(title, viewWidth/2 - rect.width()/2, viewHeight/2+rect.height()/2, paint);


    }

这里我们画了一个居中显示的圆和文本,下面来看一下效果图
这里写图片描述
看着效果感觉是没什么毛病,但当我们把字体放大一点后,发现文字并没有居中。
这里写图片描述
把字体设置的越大 越明显
这里写图片描述

具体原因参考
http://blog.csdn.net/carrey1989/article/details/10399727

按照他的博客进行处理,解决了我的问题O(∩_∩)O

最后看一下效果图

这里写图片描述
这里写图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值