读书人

android自定义视图例证详解

发布时间: 2013-02-15 15:46:56 作者: rapoo

android自定义视图例子详解
本例子程序的最终效果图
android自定义视图例证详解
(一)自定义View类
import android.content.Context;import android.content.res.TypedArray;import android.graphics.Canvas;import android.graphics.Color;import android.graphics.Paint;import android.util.AttributeSet;import android.view.View;
public class CrossView extends View { private float mRotation; private Paint mPaint; public CrossView( Context context, AttributeSet attrs ) {//AttributeSet对象在实例化时被系统传给了视图 super( context, attrs ); //start 创建paint对象 mPaint = new Paint(); mPaint.setAntiAlias( true ); mPaint.setColor( 0xFFFFFFFF ); //end 创建paint对象 //使用obtainStyledAttributes方法来创建一个TypedArray,这是访问存储于AttributeSet中的值的一个方便类,这类执行内部缓存, //所以当你结束使用它之后随时调用回收函数。注意:需同时使用<declare-styleable>名称和<arr>名称的访问自定义属性 TypedArray arr = getContext().obtainStyledAttributes( attrs,R.styleable.cross ); int color = arr.getColor( R.styleable.cross_android_color, Color.WHITE ); float rotation = arr.getFloat( R.styleable.cross_rotation, 0f ); //remember to call this when finished arr.recycle(); setColor(color); setRotation(rotation); } private void setRotation( float rotation ) { // TODO Auto-generated method stub mRotation = rotation; } private void setColor( int color ) { // TODO Auto-generated method stub mPaint.setColor( color ); } //重写onMeasure方法 @Override protected void onMeasure( int widthMeasureSpec, int heightMeasureSpec ) { // TODO Auto-generated method stub super.onMeasure( widthMeasureSpec, heightMeasureSpec ); //需要使用计算好的宽和高的值作为该方法的实参 setMeasuredDimension( calculateMeasure(widthMeasureSpec), calculateMeasure(heightMeasureSpec) ); } float[] mPoints = {0.5f,0f,0.5f,1f,0f,0.5f,1f,0.5f}; @Override protected void onDraw( Canvas canvas ) { // TODO Auto-generated method stub super.onDraw( canvas ); canvas.save();//所有的在画布上绘图的调用都应当受对应的sava()和restore()的约束 int scale = getWidth(); canvas.scale( scale, scale ); canvas.rotate( mRotation ); canvas.drawLines( mPoints, mPaint );//绘制十字的两条线 canvas.restore();//所有的在画布上绘图的调用都应当受对应的sava()和restore()的约束 } private static final int DEFAULT_SIZE = 100;//默认的试图尺寸 //实现计算测量值的代码 private int calculateMeasure(int measureSpec){ int result = ( int ) ( DEFAULT_SIZE*getResources().getDisplayMetrics().density ); int specMode = MeasureSpec.getMode( measureSpec );//在MeasureSpec中检索模式 int specSize = MeasureSpec.getSize( measureSpec );//在MeasureSpec中检索尺寸 //基于模式选择尺寸 if(specMode == MeasureSpec.EXACTLY){ result = specSize; }else if(specMode == MeasureSpec.AT_MOST){ result = Math.min( result, specSize ); } return result; }}(二)自定义属性
<?xml version="1.0" encoding="utf-8"?><!-- 该文件被放置在res/values/目录下 --><resources> <!-- 声明属性 --> <declare-styleable name="cross"> <attr name="android:color"/> <attr name="rotation" format="string"/> </declare-styleable> <!-- <attr name="test" format="string"/> <declare-styleable name="foo"> <attr name="test"/> </declare-styleable> <declare-styleable name="bar"> <attr name="test"/> </declare-styleable> --></resources>
(三)在XML中使用自定义View
<?xml version="1.0" encoding="utf-8"?> <!-- 要使用在XML中的自定义属性,首先必须为视图声明命名空间 --><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:example="http://schemas.android.com/apk/res/com.example" android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="fill_parent" > <!-- 添加CrossView --> <com.example.CrossView android:layout_width="wrap_content" android:layout_height="wrap_content" /> <com.example.CrossView android:layout_width="wrap_content" android:layout_height="wrap_content" example.rotation="30" android:color="#0000FF"/> /> <com.example.CrossView android:layout_width="wrap_content" android:layout_height="wrap_content" example.rotation="40" android:color="#FFFF00" /></LinearLayout>

读书人网 >Android

热点推荐