自定义View

来源:互联网 发布:怎么删除淘宝评论记录 编辑:程序博客网 时间:2024/06/05 19:13

在学习自定义View的路上碰到了很多坑,首先如何定义一个自定义的view。不要急。一步一步看。

1.在工程res目录下新建一个attr文件
2. 重写onMeasure()方法。
3.重写onDraw()方法。

首先第一步创建一个attr文件`

<resources><attr name="textcolor" format="color"/><attr name="textsize" format="dimension"/><attr name="text" format="string"/><declare-styleable name="DefineView">    <attr name="textcolor"/>    <attr name="textsize"/>    <attr name="text"/></declare-styleable></resources>

然后在重写onMeasure方法之前需要获取对应属性。

 public DefineView(Context context, AttributeSet attrs,int defStyleAttr) {        super(context, attrs, defStyleAttr);        TypedArray a = context.getTheme().obtainStyledAttributes(attrs, R.styleable.DefineView, defStyleAttr, 0);        int n = a.getIndexCount();        for (int i = 0; i < n; i++) {            int attr = a.getIndex(i);            switch (attr) {                case R.styleable.DefineView_textcolor:                    textcolor = a.getColor(attr, Color.GREEN);                    break;                case R.styleable.DefineView_textsize:                    textsize = a.getDimensionPixelSize(attr, (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP, 16, getResources().getDisplayMetrics()));                    break;                case R.styleable.DefineView_text:                    text = a.getString(attr);                    break;            }        }        a.recycle();        mPaint = new Paint();        mRect = new Rect();        mPaint.setTextSize(textsize);        mPaint.getTextBounds(text, 0, text.length(), mRect);    }

第二步重写onMeasure()方法。

  @Override     protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {         int widthMode=MeasureSpec.getMode(widthMeasureSpec);        int heightMode = MeasureSpec.getMode(heightMeasureSpec);        int width = 0;        int height = 0;        if (widthMode == MeasureSpec.EXACTLY) {            width = widthSize;          } width = getPaddingLeft() + getPaddingRight() + mRect.width();        }        if (heightMode == MeasureSpec.EXACTLY) {            height = heightSize;        }   height = getPaddingBottom() + getPaddingTop() + mRect.height();            }         setMeasuredDimension(width, height);      }

在重写onMeasure()方法中,有三种模式,
EXACTLY:代表view的宽高为精确值或者matchParent。

ATMOST:代表子view的宽高为wrapParen

UNSPECIFIED:代表子view想多大就多大,基本很少用到。
最后记得调用setMeasuredDimension(width, height);在onMeasure方法的源码中最后也是调用了这个方法,将宽高穿进去测量view的宽高。

第三步重写onDraw方法

    protected void onDraw(Canvas canvas) {        super.onDraw(canvas);        mPaint.setColor(Color.RED);        mPaint.setAntiAlias(true);        canvas.drawRect(0,0,getMeasuredWidth(),getMeasuredHeight(),mPaint);        mPaint.setColor(textcolor);        canvas.drawText(text,0, getHeight()/2+mRect.height()/2,mPaint);    }

然后在xml文件使用:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"    xmlns:custom="http://schemas.android.com/apk/res-auto"    xmlns:tools="http://schemas.android.com/tools"    android:layout_width="match_parent"    android:layout_height="match_parent"    android:paddingBottom="@dimen/activity_vertical_margin"    android:paddingLeft="@dimen/activity_horizontal_margin"    android:paddingRight="@dimen/activity_horizontal_margin"    android:paddingTop="@dimen/activity_vertical_margin"    tools:context="com.example.ljingya.defineview.MainActivity">    <com.example.ljingya.defineview.DefineView        android:layout_width="match_parent"        android:layout_height="wrap_content"        custom:text="东京热"        android:padding="10dp"        custom:textcolor="#fff"        custom:textsize="20sp" /></RelativeLayout>

上下效果:
这里写图片描述

0 0
原创粉丝点击