王学岗自定义控件(二)

来源:互联网 发布:达内大数据 编辑:程序博客网 时间:2024/06/03 18:25

接上一篇文章;我们在部署完项目后,虽然有打印输出,但是在屏幕上却没有任何显示这里写图片描述
这是因为我们还没有调用onDraw()方法的缘故!onDraw()方法是把内容绘制到控件,调用这个方法我们需要两个类的帮助,Paint类和Canvas的帮助,paint是画笔,联想下我们在实际生活中,绘画的时候只需要一支画笔,在android也是这样,既然只需要一支画笔我们就可以把画笔定义在构造方法中!不说了看修改后的MyTextView的代码 !

package com.example.zi_ding_yi_kong_jian.myview;import com.example.zi_ding_yi_kong_jian.R;import android.content.Context;import android.content.res.TypedArray;import android.graphics.Canvas;import android.graphics.Color;import android.graphics.Paint;import android.graphics.Paint.Style;import android.util.AttributeSet;import android.util.Log;import android.util.TypedValue;import android.view.View;public class MyTextView extends View {    private int myTextColor;    private int defaultValue;    private int myTestSize;    private String myText;    private Paint myPaint;    public MyTextView(Context context, AttributeSet attrs, int defStyle) {        super(context, attrs, defStyle);        TypedArray ta = context.obtainStyledAttributes(attrs,                R.styleable.myTextView);        myText = ta.getString(R.styleable.myTextView_myText);        myTextColor = ta                .getColor(R.styleable.myTextView_myTextColor, Color.RED);        defaultValue = (int) TypedValue.applyDimension(                TypedValue.COMPLEX_UNIT_SP, 12, getResources()                        .getDisplayMetrics());        myTestSize = (int) ta.getDimension(R.styleable.myTextView_myTextSize,                defaultValue);        ta.recycle();// 要回收 Be sure to call recycle() when done with them        Log.i("zhang_xin", "myText=" + myText + "   myTextColor=" + myTextColor                + "  MyTestSize=" + myTestSize);        //在构造方法中实例化画笔        initPaint();    }    private void initPaint() {        myPaint = new Paint();        myPaint.setColor(Color.BLACK);        myPaint.setTextSize(50);        myPaint.setStyle(Style.STROKE);        myPaint.setAntiAlias(true);    }    public MyTextView(Context context, AttributeSet attrs) {        this(context, attrs, 0);    }    public MyTextView(Context context) {        this(context, null);    }    @Override    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {        // TODO Auto-generated method stub        super.onMeasure(widthMeasureSpec, heightMeasureSpec);    }    @Override    protected void onDraw(Canvas canvas) {        super.onDraw(canvas);        canvas.drawText(myText, 100, 100, myPaint);    }}

但是这样还有一个问题;我们先看下我们的布局中的MyTextView

 <com.example.zi_ding_yi_kong_jian.myview.MyTextView        android:layout_width="wrap_content"        android:layout_height="wrap_content"        myandroid:myText="@string/myText"        myandroid:myTextColor="#13579a"        myandroid:myTextSize="10sp"        android:background="#08642d" />

它的宽和高都是包裹内容,但效果却是与match_parent一样,匹配父容器,
这里写图片描述
我们当然可以为他设置固定的值但是这样却很不方便,这我们就用到了onMeasure()方法;该方法就是测量view在屏幕中的长和宽!如果我们不重写他默认调用的就是父类的方法!onMeasure()方法在onDraw()方法之前调用,先测量在绘制!
父容器会调用onMeasure()方法,传进两个参数,这两个参数是父容器的宽高模式!我们首先也要判断容器的宽高模式是MeasureSpec.EXACTLY(固定值或者是match_parent)还是MeasureSpec.AT_MOST(wrap_content);我们来看下代码

package com.example.zi_ding_yi_kong_jian.myview;import com.example.zi_ding_yi_kong_jian.R;import android.content.Context;import android.content.res.TypedArray;import android.graphics.Canvas;import android.graphics.Color;import android.graphics.Paint;import android.graphics.Paint.Style;import android.graphics.Rect;import android.util.AttributeSet;import android.util.Log;import android.util.TypedValue;import android.view.View;import android.view.View.MeasureSpec;public class MyTextView extends View {    private int myTextColor;    private int defaultValue;    private int myTestSize;    private String myText;    private Paint myPaint;    private Rect bounds;    public MyTextView(Context context, AttributeSet attrs, int defStyle) {        super(context, attrs, defStyle);        TypedArray ta = context.obtainStyledAttributes(attrs,                R.styleable.myTextView);        myText = ta.getString(R.styleable.myTextView_myText);        myTextColor = ta                .getColor(R.styleable.myTextView_myTextColor, Color.RED);        defaultValue = (int) TypedValue.applyDimension(                TypedValue.COMPLEX_UNIT_SP, 12, getResources()                        .getDisplayMetrics());        myTestSize = (int) ta.getDimension(R.styleable.myTextView_myTextSize,                defaultValue);        ta.recycle();// 要回收 Be sure to call recycle() when done with them        Log.i("zhang_xin", "myText=" + myText + "   myTextColor=" + myTextColor                + "  MyTestSize=" + myTestSize);        // 在构造方法中实例化画笔        initPaint();    }    private void initPaint() {        myPaint = new Paint();        myPaint.setColor(Color.BLACK);        myPaint.setTextSize(20);        myPaint.setStyle(Style.STROKE);        myPaint.setAntiAlias(true);        bounds = new Rect();        // 它返回Rect由文字所占据。但根据这个答案它,然后返回不同的TextView的宽度/高度。        myPaint.getTextBounds(myText, 0, myText.length(), bounds);    }    public MyTextView(Context context, AttributeSet attrs) {        this(context, attrs, 0);    }    public MyTextView(Context context) {        this(context, null);    }    @Override    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {        //默认是父容器的宽高模式        int widthMode = MeasureSpec.getMode(widthMeasureSpec);        int widthSize = MeasureSpec.getSize(widthMeasureSpec);        Log.i("zhangxin",widthSize+"");        int tempwidth = widthSize;        if (widthMode == MeasureSpec.AT_MOST) {            // 控件的宽度=所右内边距+文字的宽度。文字的宽度和高度可以在画笔中计算出            tempwidth = getPaddingLeft() + getPaddingRight() + bounds.width();        }        int heightMode = MeasureSpec.getMode(heightMeasureSpec);        int heightSize = MeasureSpec.getSize(heightMeasureSpec);        int tempheight = heightSize;        if (heightMode == MeasureSpec.AT_MOST) {            tempheight = getPaddingTop() + getPaddingBottom() + bounds.height();        }        // 不需要调用父类的方法,但要把测量好的高度和宽度告诉父容器        // super.onMeasure(widthMeasureSpec, heightMeasureSpec);        setMeasuredDimension(tempwidth, tempheight);        Log.i("zhang_xin", "tempwidth:" + tempwidth + "  " + "tempheight:"                + tempheight);    }    @Override    protected void onDraw(Canvas canvas) {        super.onDraw(canvas);        // getwidth(),getHeight()得到绘制后view的宽度和高度        Log.i("zhang_xin", "getWidth():" + getWidth() + "  " + "getHeight:"                + getHeight());        Log.i("zhang_xin", "bounds.width():" + bounds.width() + "  "                + "bounds.height():" + bounds.height());        Log.i("zhang_xin", "getMeasuredWidth():" + getMeasuredWidth() + "  " + "getMeasuredHeight():"                + getMeasuredHeight());        canvas.drawText(myText, (getWidth() - bounds.width()) / 2,                (getHeight() + bounds.height()) / 2, myPaint);    }}

看下效果
这里写图片描述
另外本文还有个缺点,就是关于drawText的参数的问题,我给大家推荐三个链接,相信大家读完就明白了!哎我读完了,但还是有点迷糊
http://www.jcodecraeer.com/a/anzhuokaifa/androidkaifa/2013/0409/1143.html
http://blog.csdn.net/lovexieyuan520/article/details/43153275
http://mikewang.blog.51cto.com/3826268/871765/

0 0
原创粉丝点击