Android自定义View基础

来源:互联网 发布:mysql 查看梭镖 编辑:程序博客网 时间:2024/05/16 06:11

在项目中 我们或多或少会用到自定义View 下面简单介绍一下自定义View的使用基础

1自定义View的属性,首先在res/values/下建立一个attrs.xml文件,在里面定义我们的属性和声明我们的整个样式。

<?xml version="1.0" encoding="utf-8"?><resources>    <attr name="myText"  format="string"/>    <attr name="myTextColor" format="color"/>    <attr name="myTextSize" format="dimension"/>        <declare-styleable name="CustomMyView">          <attr name="myText"/>        <attr name="myTextColor"/>        <attr name="myTextSize"/>    </declare-styleable></resources>



2.重写OnDraw、onMeasure方法

@Overrideprotected void onDraw(Canvas canvas) {// TODO Auto-generated method stubsuper.onDraw(canvas);//设置背景色myPaint.setColor(Color.YELLOW);          canvas.drawRect(0, 0, getMeasuredWidth(), getMeasuredHeight(), myPaint);         //设置字体颜色myPaint.setColor(myColor);          canvas.drawText(myText, getWidth() / 2 - myRect.width() / 2, getHeight() / 2 + myRect.height() / 2, myPaint); }


@Override  protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec)  {      int widthMode = MeasureSpec.getMode(widthMeasureSpec);      int widthSize = MeasureSpec.getSize(widthMeasureSpec);      int heightMode = MeasureSpec.getMode(heightMeasureSpec);      int heightSize = MeasureSpec.getSize(heightMeasureSpec);      int width;      int height ;      if (widthMode == MeasureSpec.EXACTLY)      {          width = widthSize;      } else      {          myPaint.setTextSize(mySize);          myPaint.getTextBounds(myText, 0, myText.length(), myRect);          float textWidth = myRect.width();          int desired = (int) (getPaddingLeft() + textWidth + getPaddingRight());          width = desired;      }        if (heightMode == MeasureSpec.EXACTLY)      {          height = heightSize;      } else      {          myPaint.setTextSize(mySize);          myPaint.getTextBounds(myText, 0, myText.length(), myRect);          float textHeight = myRect.height();          int desired = (int) (getPaddingTop() + textHeight + getPaddingBottom());          height = desired;      }        setMeasuredDimension(width, height);  }  


重写onMeasure是为了防止布局中设置高宽为wrap_content时撑满整个布局

3.在我们布局中使用

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"    xmlns:tools="http://schemas.android.com/tools"    xmlns:custom="http://schemas.android.com/apk/res/com.example.mycustomview"      android:layout_width="match_parent"    android:layout_height="match_parent">        <com.example.mycustomview.MyCustomTextView         android:id="@+id/myView"        android:layout_width="wrap_content"        android:layout_height="wrap_content"        custom:myText="this is myCustom view"        custom:myTextSize="20sp"        android:layout_centerInParent="true"        android:padding="10dp"/></RelativeLayout>

记得加上
xmlns:custom="http://schemas.android.com/apk/res/你的自定义View路径" 

下面是全部的代码

import android.content.Context;import android.content.res.TypedArray;import android.graphics.Canvas;import android.graphics.Color;import android.graphics.Paint;import android.graphics.Rect;import android.util.AttributeSet;import android.util.TypedValue;import android.view.View;public class MyCustomTextView extends View{private String myText;private int myColor;private int mySize;private Paint myPaint;private Rect myRect;public MyCustomTextView(Context context) {// TODO Auto-generated constructor stubthis(context, null);}public MyCustomTextView(Context context, AttributeSet attrs) {this(context, attrs, 0);// TODO Auto-generated constructor stub}public MyCustomTextView(Context context, AttributeSet attrs,int defStyleAttr) {super(context, attrs, defStyleAttr);// TODO Auto-generated constructor stubTypedArray ta = context.getTheme().obtainStyledAttributes(attrs, R.styleable.CustomMyView, defStyleAttr, 0);int indexCount = ta.getIndexCount();for (int i = 0; i < indexCount; i++) {int index = ta.getIndex(i);switch (index) {case R.styleable.CustomMyView_myText:myText = (String) ta.getText(index);break;case R.styleable.CustomMyView_myTextColor:myColor = ta.getColor(index, Color.BLUE);break;case R.styleable.CustomMyView_myTextSize:mySize = ta.getDimensionPixelSize(index, (int)TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP, 18, getResources().getDisplayMetrics()));break;default:break;}ta.recycle();myPaint = new Paint();myPaint.setTextSize(mySize);myRect = new Rect();myPaint.getTextBounds(myText, 0, myText.length(), myRect);}}@Overrideprotected void onDraw(Canvas canvas) {// TODO Auto-generated method stubsuper.onDraw(canvas);//设置背景色myPaint.setColor(Color.YELLOW);          canvas.drawRect(0, 0, getMeasuredWidth(), getMeasuredHeight(), myPaint);         //设置字体颜色myPaint.setColor(myColor);          canvas.drawText(myText, getWidth() / 2 - myRect.width() / 2, getHeight() / 2 + myRect.height() / 2, myPaint); }@Override  protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec)  {      int widthMode = MeasureSpec.getMode(widthMeasureSpec);      int widthSize = MeasureSpec.getSize(widthMeasureSpec);      int heightMode = MeasureSpec.getMode(heightMeasureSpec);      int heightSize = MeasureSpec.getSize(heightMeasureSpec);      int width;      int height ;      if (widthMode == MeasureSpec.EXACTLY)      {          width = widthSize;      } else      {          myPaint.setTextSize(mySize);          myPaint.getTextBounds(myText, 0, myText.length(), myRect);          float textWidth = myRect.width();          int desired = (int) (getPaddingLeft() + textWidth + getPaddingRight());          width = desired;      }        if (heightMode == MeasureSpec.EXACTLY)      {          height = heightSize;      } else      {          myPaint.setTextSize(mySize);          myPaint.getTextBounds(myText, 0, myText.length(), myRect);          float textHeight = myRect.height();          int desired = (int) (getPaddingTop() + textHeight + getPaddingBottom());          height = desired;      }        setMeasuredDimension(width, height);  }  }



0 0