Android开发之自定义View(视图)

来源:互联网 发布:虚拟语气 知 识要点 编辑:程序博客网 时间:2024/05/27 21:02

第一个例子:

 View类是Android的一个超类,这个类几乎包含了所有的屏幕类型。每一个View都有一个用于绘图的画布,这个画布可以进行任意扩展。在游戏开发中往往需要自定义视图(View),这个画布的功能更能满足我们在游戏开发中的需要。在Android中,任何一个View类都只需重写onDraw 方法来实现界面显示,自定义的视图可以是复杂的3D实现,也可以是非常简单的文本形式等。

        为了实现自定义View,需要创建一个新的类,然后重写onDraw方法,在此需要注意,新创建的类MyView要继承View基类,同时还要加入有参数的两个构造方法MyView(Context context)和MyView(Contextcontext,AttributeSet attr),否则编译运行无法通过。

在onDraw方法中,初始化了一个画笔对象myPaint,设置画笔颜色,还有文字大小,填充等属性。再利用本方法传入的参数canvas画布完成一幅条形统计图的绘制。具体代码如下:

  • package com.viewTest;
  • import android.content.Context;
  • import android.graphics.Canvas;
  • import android.graphics.Color;
  • import android.graphics.Paint;
  • import android.graphics.Rect;
  • import android.graphics.Paint.Style;
  • import android.util.AttributeSet;
  • import android.view.View;
  • public class MyView extends View {
  •     public MyView(Context context) {
  •         super(context);
  •         // TODO Auto-generated constructor stub
  •     }
  •     public MyView(Context context,AttributeSet attr) {
  •         super(context,attr);
  •     }
  •     private Paint myPaint;
  •     private static final String myString1 = "2006-2011上半年中国移动互联网行业各年度投资情况";
  •     private static final String myString2 = "来源:清科研究中心 2011.08";
  •     @Override
  •     protected void onDraw(Canvas canvas) {
  •         // TODO Auto-generated method stub
  •         super.onDraw(canvas);
  •         myPaint = new Paint();
  •         //绘制标题
  •         myPaint.setColor(Color.BLACK); //设置画笔颜色
  •         myPaint.setTextSize(18);//设置文字大小
  •         canvas.drawText(myString1, 20, 20, myPaint);
  •         //绘制坐标轴
  •         canvas.drawLine(50, 100, 50, 500, myPaint);//纵坐标轴
  •         canvas.drawLine(50, 500, 400, 500, myPaint);//横坐标轴
  •         int[] array1 = new int[]{0, 50, 100, 150, 200, 250, 300, 350};
  •         //绘制纵坐标刻度
  •         myPaint.setTextSize(10);//设置文字大小
  •         canvas.drawText("单位:百万美元", 20, 90, myPaint);
  •         for (int i = 0; i < array1.length; i++) {
  •             canvas.drawLine(50, 500 - array1, 54, 500 - array1, myPaint);
  •             canvas.drawText(array1 + "", 20, 500 - array1, myPaint);
  •         }
  •         //绘制横坐标文字
  •         String[] array2 = new String[]{"2008年", "2009年", "2010年", "2011上半年"};
  •         for (int i = 0; i < array2.length; i++) {
  •             canvas.drawText(array2, array1 + 80, 520, myPaint);
  •         }
  •         //绘制条形图
  •         myPaint.setColor(Color.BLUE); //设置画笔颜色
  •         myPaint.setStyle(Style.FILL); //设置填充
  •         canvas.drawRect(new Rect(90, 500 - 56, 110, 500), myPaint);//画一个矩形,前两个参数是矩形左上角坐标,后两个参数是右下角坐标
  •         canvas.drawRect(new Rect(140, 500 - 98, 160, 500), myPaint);//第二个矩形
  •         canvas.drawRect(new Rect(190, 500 - 207, 210, 500), myPaint);//第三个矩形
  •         canvas.drawRect(new Rect(240, 500 - 318, 260, 500), myPaint);//第四个矩形
  •         myPaint.setColor(Color.BLACK); //设置画笔颜色
  •         canvas.drawText("56.32", 88, 500 - 58, myPaint);//第一个矩形的数字说明
  •         canvas.drawText("98.00", 138, 500 - 100, myPaint);
  •         canvas.drawText("207.65", 188, 500 - 209, myPaint);
  •         canvas.drawText("318.30", 238, 500 - 320, myPaint);
  •         //绘制出处
  •         myPaint.setColor(Color.BLACK); //设置画笔颜色
  •         myPaint.setTextSize(16);//设置文字大小
  •         canvas.drawText(myString2, 20, 560, myPaint);
  •     }
  • }


复制代码
然后将我们自定义的View 加入到main.xml 布局文件中, 在这里设置View的背景色为白色,是为了更好地展现其中的内容。代码如下:

  • <?xml version="1.0" encoding="utf-8"?>
  • <LinearLayout xmlns:android="schemas.android.com/apk/res/android"
  •     android:layout_width="fill_parent"
  •     android:layout_height="fill_parent"
  •     android:orientation="vertical" >
  •     <TextView
  •         android:layout_width="fill_parent"
  •         android:layout_height="wrap_content"
  •         android:text="@string/hello" />
  •     <Button
  •         android:layout_width="match_parent"
  •         android:layout_height="40dip"
  •         android:text="下一张图" />
  •     <com.viewTest.MyView
  •         android:layout_width="fill_parent"
  •         android:layout_height="wrap_content"
  •         android:background="#FFFFFF"/>
  • </LinearLayout>


复制代码
初始的activity.java文件并不需要修改。最后的效果如下图所示:

 

第二个例子:

android提供了精巧和有力的组件化模型构建用户的UI部分。主要是基于布局类:View和ViewGroup。在此基础上,android平台提供了大量的预制的View和ViewGroup子类,即布局(layout)和窗口小部件(widget)。可以用它们构建自己的UI。

如果没有符合你需求的预制窗口小部件,你可以创建自己的视图子类。如果只是对已存在的窗口小部件或者布局做小的调整,只需继承该类,覆盖相关的方法。

创建你自己的View子类可以更精确控制视图元素的外观和功能。

  • 可创建完整的自定义渲染视图类型,比如创建一个2d的控制条;
  • 可将一组视图组件合成为一个新的单一组件,比如双选的列表,选择省和市;
  • 覆盖EditText组件,比如notepad tutorial中的示例;
  • 捕捉其他事件比如按键事件,并执行自定义的处理方式,比如在游戏中。

基本方法

总的来说,创建自定义的视图组件步骤是:

  1. 创建自己的类,继承已经存在的View类或者子类;
  2. 覆盖超类的一些方法。这些超类的方法一般以“on”开头,比如onDraw()方法等等;
  3. 使用新创建的扩展类。一旦完成,你的新扩展类就可以用于所有View使用的地方。

注意:扩展类可以定义为内部类,在你创建的Activity类之中。这很有用,因为这样可以控制外界的访问,但是这不是必须的,因为你可能需要一个public的自定义View类供更广泛的使用。

完全自定义组件

完全自定义的组件可以创建图形组件显示在你需要的任何地方。

步骤如下:

  1. 可以继承的最通用的视图类是View,可以继承它创建自定义的组件超类;
  2. 可以提供构造方法,并通过xml文件获取属性值和参数;
  3. 创建自己的事件监听器,属性访问器和编辑器等等;
  4. 一般情况下会覆盖onMeasure()方法和onDraw()方法,这会让组件显示一些东西。如果都用默认的行为,onDraw()方法不做任何事情,onMeasure()方法设置一个100×100的区域;
  5. 根据需求覆盖其他on…方法。

扩展onDraw()和onMeasure()方法

onDraw()方法提供给你一个Canvas对象,在它之上可以实现任何你想要的东西,通过2d图形api。比如其他标准的后者自定义的组件,风格化的文字后者其他。

注意:这里不提供3d图形api的支持。如果你需要3d图形支持,必须继承SurfaceView而不是View,并且通过单独的线程画图。可以通过GLSurfaceViewActivity实例查看详细信息。

onMeasure()方法有些麻烦。该方法是在容器和自定义组件之间渲染的重要部分。该方法覆盖,要高效率的和精确的报告被包含区域的测量值。

总的来看,实现onMeasure()方法类似如下步骤:

  1. 调用已经覆盖的onMeasure()方法,传递长和宽规范参数;
  2. 自定义组件在onMeasure()方法中计算需要渲染的组件的长和宽,应该在规范参数的范围内;
  3. 一旦长和宽计算出来,必须调用setMeasuredDimension(int width, int height)方法,这步失败会导致异常的抛出。

一个自定义视图的示例

  • 继承View类,用于完全自定义组件;
  • 参数化的构造方法,提供更多的参数,定义在xml文件中;
  • 标准的公开方法,用于设置标签,比如setText()方法等;
  • 覆盖onMeasure方法确定渲染的组件尺寸;
  • 覆盖onDraw方法,在提供的canvas中画标签。

[代码]xml代码:

view source
print?
01<?xmlversion="1.0"encoding="utf-8"?>
02<LinearLayoutxmlns:android="http://schemas.android.com/apk/res/android"
03    android:orientation="vertical"
04    android:layout_width="fill_parent"
05    android:layout_height="fill_parent"
06    >
07    <TextView 
08        android:layout_width="fill_parent"
09        android:layout_height="wrap_content"
10        android:text="@string/hello"
11        />
12</LinearLayout>

当然上面的布局方式可以帮助我们完成简单应用的开发了,但是如果你想写一个复杂的应用,这样就有点牵强了,大家不信的话可以下源码都研究看看高手写的布局方式,如上面的布局高手通常是这样写的:

[代码]xml代码:

view source
print?
1<?xmlversion="1.0"encoding="utf-8"?>
2<A>
3    <B></B>
4</A>
5   
6其中A extends LinerLayout, B extends TextView.

为了帮助大家更容易理解,我写了一个简单的Android View Demo,具体步骤如下:

首先新建一个Android工程 命名为ViewDemo。

然后自定义一个View类,命名为MyView(extends View),代码如下:

[代码]java代码:

view source
print?
01package com.android.tutor;
02   
03import android.content.Context;
04import android.graphics.Canvas;
05import android.graphics.Color;
06import android.graphics.Paint;
07import android.graphics.Rect;
08import android.graphics.Paint.Style;
09import android.util.AttributeSet;
10import android.view.View;
12public class MyView extendsView {
13    privatePaint mPaint;
14    privateContext mContext;
15    privatestaticfinal String mString ="Welcome to Mr Wei's blog";
17    publicMyView(Context context) {
18        super(context);
19    }
21    publicMyView(Context context,AttributeSet attr) {
22        super(context,attr);
23    }
25    @Override
26    protectedvoidonDraw(Canvas canvas) {
27        // TODO Auto-generated method stub
28        super.onDraw(canvas);
30        mPaint =newPaint();
32        //设置画笔颜色
33        mPaint.setColor(Color.RED);
35        //设置填充
36        mPaint.setStyle(Style.FILL);
38        //画一个矩形,前俩个是矩形左上角坐标,后面俩个是右下角坐标
39        canvas.drawRect(newRect(10,10,100,100), mPaint);
41        mPaint.setColor(Color.BLUE);
42        //绘制文字
43        canvas.drawText(mString,10,110, mPaint);
44    }
45}

然后将我们自定义的View加入到main.xml布局文件中,代码如下:

[代码]xml代码:

view source
print?
01<?xmlversion="1.0"encoding="utf-8"?>
02<LinearLayoutxmlns:android="http://schemas.android.com/apk/res/android"
03    android:orientation="vertical"
04    android:layout_width="fill_parent"
05    android:layout_height="fill_parent"
06    >
07    <TextView 
08        android:layout_width="fill_parent"
09        android:layout_height="wrap_content"
10        android:text="@string/hello"
11        />
12    <com.android.tutor.MyView
13        android:layout_width="fill_parent"
14        android:layout_height="fill_parent"
15        />
16</LinearLayout>

最后执行,效果如下图:

Android-View

 

原创粉丝点击