代码改变世界

View编程(7): 自定义View_03

2011-12-14 16:41  tang768168  阅读(229)  评论(0编辑  收藏  举报

根据android的api demo中提供的例子,自己尝试写一个自定义View,算是做个复习。

这篇博客是建立在View编程(5): 自定义View_01_ApiDemo源码研究View编程(6): 自定义View_02_ApiDemo源码研究基础之上。

以上两篇博客是对某些知识点的原理性分析,该篇也算是一个小结,没有什么原理可说。好嘞,废话到此为止。

1. 自定义View

MyView.java源码

  1. package mark.zhang;  
  2.   
  3. import android.content.Context;  
  4. import android.graphics.Canvas;  
  5. import android.graphics.Color;  
  6. import android.graphics.Paint;  
  7. import android.graphics.Paint.Style;  
  8. import android.util.AttributeSet;  
  9. import android.view.View;  
  10.   
  11.   
  12. public class MyView extends View {  
  13.     Paint mPaint;  
  14.       
  15.     public MyView(Context context) {  
  16.         super(context);  
  17.     }  
  18.       
  19.     /** 
  20.      * 该构造方法必须有,否则会报错 
  21.      *  
  22.      * @param context 
  23.      * @param attrs 
  24.      */  
  25.     public MyView(Context context, AttributeSet attrs){  
  26.         super(context, attrs);  
  27.     }  
  28.       
  29.     @Override  
  30.     public void onDraw(Canvas canvas){  
  31.         super.onDraw(canvas);  
  32.         mPaint = new Paint();  
  33.         mPaint.setStyle(Style.FILL); //设置填充  
  34.         mPaint.setColor(Color.RED);  
  35.         canvas.drawRect(2010100100, mPaint); //绘制矩形  
  36.           
  37.         mPaint.setColor(Color.BLUE);  
  38.         canvas.drawText("this is a rectangle"10120, mPaint);  
  39.     }  
  40. }  

这里需要注意:

<1> 继承View需要也是必需的是,重写某个构造方法。

<2> 由于是在xml文件中加载该自定义控件,需要也是必须写下面这个构造方法:

  1. public MyView(Context context, AttributeSet attrs){  
  2.         super(context, attrs);  
  3. }  

否则会报错:

  1. 08-27 17:18:20.335: ERROR/AndroidRuntime(7330): Caused by: java.lang.NoSuchMethodException: MyView(Context,AttributeSet)  
  2. 08-27 17:18:20.335: ERROR/AndroidRuntime(7330):     at java.lang.Class.getMatchingConstructor(Class.java:674)  
  3. 08-27 17:18:20.335: ERROR/AndroidRuntime(7330):     at java.lang.Class.getConstructor(Class.java:486)  
  4. 08-27 17:18:20.335: ERROR/AndroidRuntime(7330):     at android.view.LayoutInflater.createView(LayoutInflater.java:475)  

2. main.xml

  1. <?xml version="1.0" encoding="utf-8"?>  
  2. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"  
  3.     xmlns:mark="http://schemas.android.com/apk/res/mark.zhang"  
  4.     android:orientation="vertical" android:layout_width="fill_parent"  
  5.     android:layout_height="fill_parent">  
  6.   
  7.     <mark.zhang.MyView android:layout_width="fill_parent"  
  8.         android:layout_height="wrap_content" mark:textColor="#FFFFFFFF"  
  9.         mark:textSize="22dp" />  
  10. </LinearLayout>  

提示:

<1> 多了一个命名空间xmlns:mark="http://schemas.android.com/apk/res/mark.zhang",注意mark.zhang是该应用的包名称。

<2> 使用自定义控件mark.zhang.MyView

<3> mark:textColor="#FFFFFFFF" mark:textSize="22dp"是使用自定义的属性。该属性文件res/values/attrs.xml

3. attrs.xml

我们不仅可以自定义控件,还可以自定义属性。

  1. <?xml version="1.0" encoding="utf-8"?>  
  2. <resources>  
  3.     <declare-styleable name="MyView">  
  4.         <attr name="textColor" format="color" />  
  5.         <attr name="textSize" format="dimension" />  
  6.     </declare-styleable>  
  7. </resources>  

回头想一想,为何在main.xml文件中,使用mark:×× 形式来引用该属性呢?

恩,因为在main.xml文件中命名空间的名称采用的是mark。所以这里也必须使用mark:××形式。
4. Activity

很简单,就是加载xml文件。

  1. package mark.zhang;  
  2.   
  3. import android.app.Activity;  
  4. import android.os.Bundle;  
  5.   
  6. public class ViewCustomTestActivity extends Activity {  
  7.       
  8.     @Override  
  9.     public void onCreate(Bundle savedInstanceState) {  
  10.         super.onCreate(savedInstanceState);  
  11.         setContentView(R.layout.main);  
  12.     }  
  13. }  

5. 效果

 

转载地址:http://blog.csdn.net/androidbluetooth/article/details/6725005