Android自定义View基础

在项目中 我们或多或少会用到自定义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方法

@Override
	protected void onDraw(Canvas canvas) {
		// TODO Auto-generated method stub
		super.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 stub
		this(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 stub
		TypedArray 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);
		}
	}
	
	@Override
	protected void onDraw(Canvas canvas) {
		// TODO Auto-generated method stub
		super.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
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值