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中的示例;
- 捕捉其他事件比如按键事件,并执行自定义的处理方式,比如在游戏中。
基本方法
总的来说,创建自定义的视图组件步骤是:
- 创建自己的类,继承已经存在的View类或者子类;
- 覆盖超类的一些方法。这些超类的方法一般以“on”开头,比如onDraw()方法等等;
- 使用新创建的扩展类。一旦完成,你的新扩展类就可以用于所有View使用的地方。
注意:扩展类可以定义为内部类,在你创建的Activity类之中。这很有用,因为这样可以控制外界的访问,但是这不是必须的,因为你可能需要一个public的自定义View类供更广泛的使用。
完全自定义组件
完全自定义的组件可以创建图形组件显示在你需要的任何地方。
步骤如下:
- 可以继承的最通用的视图类是View,可以继承它创建自定义的组件超类;
- 可以提供构造方法,并通过xml文件获取属性值和参数;
- 创建自己的事件监听器,属性访问器和编辑器等等;
- 一般情况下会覆盖onMeasure()方法和onDraw()方法,这会让组件显示一些东西。如果都用默认的行为,onDraw()方法不做任何事情,onMeasure()方法设置一个100×100的区域;
- 根据需求覆盖其他on…方法。
扩展onDraw()和onMeasure()方法
onDraw()方法提供给你一个Canvas对象,在它之上可以实现任何你想要的东西,通过2d图形api。比如其他标准的后者自定义的组件,风格化的文字后者其他。
注意:这里不提供3d图形api的支持。如果你需要3d图形支持,必须继承SurfaceView而不是View,并且通过单独的线程画图。可以通过GLSurfaceViewActivity实例查看详细信息。
onMeasure()方法有些麻烦。该方法是在容器和自定义组件之间渲染的重要部分。该方法覆盖,要高效率的和精确的报告被包含区域的测量值。
总的来看,实现onMeasure()方法类似如下步骤:
- 调用已经覆盖的onMeasure()方法,传递长和宽规范参数;
- 自定义组件在onMeasure()方法中计算需要渲染的组件的长和宽,应该在规范参数的范围内;
- 一旦长和宽计算出来,必须调用setMeasuredDimension(int width, int height)方法,这步失败会导致异常的抛出。
一个自定义视图的示例
- 继承View类,用于完全自定义组件;
- 参数化的构造方法,提供更多的参数,定义在xml文件中;
- 标准的公开方法,用于设置标签,比如setText()方法等;
- 覆盖onMeasure方法确定渲染的组件尺寸;
- 覆盖onDraw方法,在提供的canvas中画标签。
[代码]xml代码:
01
<?
xml
version
=
"1.0"
encoding
=
"utf-8"
?>
02
<
LinearLayout
xmlns: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代码:
1
<?
xml
version
=
"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代码:
01
package
com.android.tutor;
02
03
import
android.content.Context;
04
import
android.graphics.Canvas;
05
import
android.graphics.Color;
06
import
android.graphics.Paint;
07
import
android.graphics.Rect;
08
import
android.graphics.Paint.Style;
09
import
android.util.AttributeSet;
10
import
android.view.View;
12
public
class
MyView
extends
View {
13
private
Paint mPaint;
14
private
Context mContext;
15
private
static
final
String mString =
"Welcome to Mr Wei's blog"
;
17
public
MyView(Context context) {
18
super
(context);
19
}
21
public
MyView(Context context,AttributeSet attr) {
22
super
(context,attr);
23
}
25
@Override
26
protected
void
onDraw(Canvas canvas) {
27
// TODO Auto-generated method stub
28
super
.onDraw(canvas);
30
mPaint =
new
Paint();
32
//设置画笔颜色
33
mPaint.setColor(Color.RED);
35
//设置填充
36
mPaint.setStyle(Style.FILL);
38
//画一个矩形,前俩个是矩形左上角坐标,后面俩个是右下角坐标
39
canvas.drawRect(
new
Rect(
10
,
10
,
100
,
100
), mPaint);
41
mPaint.setColor(Color.BLUE);
42
//绘制文字
43
canvas.drawText(mString,
10
,
110
, mPaint);
44
}
45
}
然后将我们自定义的View加入到main.xml布局文件中,代码如下:
[代码]xml代码:
01
<?
xml
version
=
"1.0"
encoding
=
"utf-8"
?>
02
<
LinearLayout
xmlns: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(视图)
- Android开发之自定义View(视图)
- Android开发之自定义View(视图)
- Android自定义View之--理解视图层
- Android 自定义View视图
- android开发之自定义View
- Android开发之自定义View
- Android自定义View解析之视图状态及视图重绘(二)
- Android\OPhone自定义视图(View)
- Android开发之自定义View专题(一):自定义柱形图
- Android开发之自定义View专题(三):自定义GridView
- Android开发之自定义View专题(四):自定义ViewGroup
- Android开发:创建自定义视图–创建一个View类
- Android中自定义视图View
- Android中自定义视图View
- Android中自定义视图View之---前奏篇
- 【Android】自定义视图View之---Canvas和Path对象
- Android中自定义视图View之---前奏篇
- Kracker路由器破解工具
- ResultSet 两种取值 按顺序总是用的也总是 忘记 第一个是1开始 做个记录
- PDO MSSQL DEMO
- android环境搭建
- 如何使用const限定符
- Android开发之自定义View(视图)
- Android编译系统详解
- 用网上的lnmp一键安装配置了centos6.2下面的环境,用了几天后,发现php-fpm占用cpu100%
- 失望,迷茫
- 导出excel文件 解决科学计数法问题 datagridview导出字符串变数字问题
- android窗体加载过程剖析之一Activity的初始化
- myeclipse的优化
- 专题3----中东问题与一个呼唤海权的时代
- Java学习 - 24种语言执行外部命令的方法