1200字范文,内容丰富有趣,写作的好帮手!
1200字范文 > Android 自定义控件开发入门(一)

Android 自定义控件开发入门(一)

时间:2022-03-05 14:03:16

相关推荐

Android 自定义控件开发入门(一)

那么怎样来创建一个新的控件呢?

这得看需求是怎样的了。

1.需要在原生控件的基本功能上进行扩展,这个时候你只需要继承并对控件进行扩展。通过重写它的事件,onDraw ,但是始终都保持都父类方法的调用。如从已有的高级控件上继承,例如继承一个TextView。

2.需要几个控件的功能的加和,这个时候要把控件组合起来,就是通过合并几个控件来生成一个新控件。比如在ListView中用适配器来将多种控件有机的结合在一起,又如写一个控件是多个控件的组合,一般是自定义布局,可以用一个类继承一个布局。这个布局中包含多个控件。

3.白手起家自己创建一个新的控件。即直接从View,ViewGroup开始绘制控件

4.另外大家不要忘了,还有一个好用的东西<include>标签。在一个项目中我们可能会需要用到相同的布局设计,如果都写在一个xml文件中,代码显得很冗余,并且可读性也很差,所以我们可以把相同布局的代码单独写成一个模块,然后用到的时候可以通过<include /> 标签来重用layout代码。

作过Android应用开发的朋友都知道,Android的UI界面都是由View和ViewGroup及其派生类组合而成的。基于安卓UI设计原理,我们作为开发者,完全能够按照自己的意愿开发出项目定制的组件。其中,View是所有UI组件的基类,而ViewGroup是容纳这些组件的容器,其本身也是从View派生出来的。AndroidUI界面的一般结构可参见下面的示意图:

可见,作为容器的ViewGroup可以包含作为叶子节点的View,也可以包含作为更低层次的子ViewGroup,而子ViewGroup又可以包含下一层的叶子节点的View和ViewGroup。事实上,这种灵活的View层次结构可以形成非常复杂的UI布局,开发者可据此设计、开发非常精致的UI界面。

ViewGroup可以通过重写onMeasure,onLayout为加入其中的View进行布局和处理,功能十分强大,我们这次先学习View类派生自定义组件:

View组件的作用类似于JAVA中Swing里的Panel,是一个矩形的空白区域,不带有任何内容,对于Android应用的其他UI控件来说,都是继承了View组件,然后绘制出来的。所以我们通过View子类并重写View类的方法来派生我们自己的控件。

Android自定义View实现很简单:

继承View,重写构造函数、onDraw,(onMeasure)等函数,下面会逐一列举。

如果自定义的View需要有自定义的属性,需要在values下建立attrs.xml。在其中定义你的属性。在使用到自定义View的xml布局文件中需要加入xmlns:前缀="/apk/res/你的自定义View所在的包路径".在使用自定义属性的时候,使用前缀:属性名,如my:textColor="……"。

让我们先看一下View类的方法:

通常可能需要重写以下方法:

1.构造器,至少用来获取Context

2.onFinishlnflate()这是一个回调方法, 当应用从 XML 布局文件加载该组件并利用

它来构建界面之后, 该方法就会被回调。

3.onMeasure(int,int):调用该方法来检测View组件及它所包含的所有子组件的大小.

4.onlayout(boolean,int,int,int,int):当该组件需要分配其子组件的位置、大小时,

该方法就会被回调. View类中布局发生改变时会调用的方法,这个方法是所有View、ViewGroup及其派生类都具有的方法,重载该类可以在布局发生改变时作定制处理,这在实现一些特效时非常有用。

5.onSizeChanged(int,int, int, int):当该组件的大小被改变时回调该方法.

6.onDraw(canves): 当该组件将要绘制它的内容时回调该方法迸行绘制. View类中用于重绘的方法,这个方法是所有View、ViewGroup及其派生类都具有的方法,也是AndroidUI绘制最重要的方法。开发者可重载该方法,并在重载的方法内部基于参数canvas绘制自己的各种图形、图像效果。

7.onKeyDown(int,KeyEvent): 当某个键被按下时触发该方法.

8.onKayUp(int,KeyEvent), 当松开某个键时触发该方法.

9.onTrackballEvent (MotionEvent): 当发生轨迹球事件时触发该方法.

10.onTouchEvent (MotionEvent): 当发生触摸屏事件时触发该方法.

11.onWindowFocuschanged(boolean): 当该组件得到、失去焦点时触发该方法.

12.onAttachedToWindow():当把该组件放入某个窗口时触发该方法.

13.onDetachedFromWindow(): 当把该组件从某个窗口上分离时触发该方法.

14.onWindowVisibilityChanged(int):当包含该组件的窗口的可见性发生改变时触发该

方法.

另外再补充两个ViewGroup类经常重载的方法:

1.protectedvoiddispatchDraw(Canvascanvas):ViewGroup类及其派生类具有的方法,这个方法主要用于控制子View的绘制分发,重载该方法可改变子View的绘制,进而实现一些复杂的视效。

2.protectedbooleandrawChild(Canvascanvas,Viewchild,longdrawingTime)):ViewGroup类及其派生类具有的方法,这个方法直接控制绘制某局具体的子view,重载该方法可控制具体某个具体子View。

在需要开发自定义View的时候,我们不需要列举出上面所有的方法,,而是可以根据业务需要来有选择的使用·上面的方法,下面我们看一个简单的示例程序,在这个示例程序里面我们只需要重写onDraw方法就可以了!

示例程序一:

我们要写一个跟随手指移动的小球,思路很简单,只要获取到用户点击屏幕的位置,并且在该位置处重绘小球即可:

下面我们看一下程序:

我注释写的比较清楚,我就说的简略一点:

首先我们写一个类DrawView,也就是我们自定义的控件,继承自View

然后我们先写出构造器,获取到Context,这里如果用只含有Context的构造器会在xml里调用控件的时候出错,详情请看我的另外一篇博文:

/sunmc1204953974/article/details/38101057

下面我们开始写:

[java]view plaincopy //构造方法publicDrawView(Contextcontext,AttributeSetattrs){super(context,attrs);}//重写ondraw方法@OverridepublicvoidonDraw(Canvascanvas){super.onDraw(canvas);//创建画笔Paintpaint=newPaint();//设置画笔颜色paint.setColor(Color.RED);//画出小球canvas.drawCircle(circleX,circleY,circleR,paint);}

然后不要忘了设置这些数据的setter和getter,因为我们需要再使用这个View的时候加上监听才可以:

[java]view plaincopy //getset方法publicfloatgetCircleX(){returncircleX;}publicvoidsetCircleX(floatcircleX){this.circleX=circleX;}publicfloatgetCircleY(){returncircleY;}publicvoidsetCircleY(floatcircleY){this.circleY=circleY;}publicfloatgetCircleR(){returncircleR;}publicvoidsetCircleR(floatcircleR){this.circleR=circleR;}

这样我们的一个简单地自定控件就大功告成了,下面是该类的完整代码:

[java]view plaincopy packagecom.example.moveball;importandroid.content.Context;importandroid.graphics.Canvas;importandroid.graphics.Color;importandroid.graphics.Paint;importandroid.util.AttributeSet;importandroid.view.View;publicclassDrawViewextendsView{privatefloatcircleX=40;privatefloatcircleY=50;privatefloatcircleR=15;//构造方法publicDrawView(Contextcontext,AttributeSetattrs){super(context,attrs);}//重写ondraw方法@OverridepublicvoidonDraw(Canvascanvas){super.onDraw(canvas);//创建画笔Paintpaint=newPaint();//设置画笔颜色paint.setColor(Color.RED);//画出小球canvas.drawCircle(circleX,circleY,circleR,paint);}//getset方法publicfloatgetCircleX(){returncircleX;}publicvoidsetCircleX(floatcircleX){this.circleX=circleX;}publicfloatgetCircleY(){returncircleY;}publicvoidsetCircleY(floatcircleY){this.circleY=circleY;}publicfloatgetCircleR(){returncircleR;}publicvoidsetCircleR(floatcircleR){this.circleR=circleR;}}

之后我们就是像平时使用安卓原生控件那样使用就可以了,我们看一下Activity的代码:

[java]view plaincopy packagecom.example.moveball;importandroid.os.Bundle;importandroid.app.Activity;importandroid.view.Menu;importandroid.view.MotionEvent;importandroid.view.View;importandroid.view.View.OnTouchListener;publicclassMainActivityextendsActivity{//定义DrawView组件DrawViewdrawView=null;@OverrideprotectedvoidonCreate(BundlesavedInstanceState){super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);//创建DrawView组件drawView=(DrawView)this.findViewById(R.id.drawView);//为DrawView组件绑定Touch事件drawView.setOnTouchListener(newOnTouchListener(){@OverridepublicbooleanonTouch(Viewarg0,MotionEventevent){//获取坐标并改变小球的坐标drawView.setCircleX(event.getX());drawView.setCircleY(event.getY());//通知draw组件重绘drawView.invalidate();//返回true表明被执行returntrue;}});}}

以及xml格式的布局文件:

[html]view plaincopy <?xmlversion="1.0"encoding="utf-8"?><RelativeLayoutxmlns:android="/apk/res/android"xmlns:tools="/tools"android:layout_width="match_parent"android:layout_height="match_parent"tools:context=".MainActivity"><com.example.moveball.DrawViewandroid:id="@+id/drawView"android:layout_width="match_parent"android:layout_height="match_parent"></com.example.moveball.DrawView></RelativeLayout>

这样一个简单的例子就呈现在大家面前了,无论是多么复杂的自定义控件,思路总是这样子的,大家是不是觉得怪怪的,对了,作为一个控件,我们居然还要为了他的实现为其增加麻烦的监听,这就是因为我们重写的方法太少的原因,下一讲再给大家介绍一个经常重写的方法:publicbooleanonTouchEvent(MotionEventevent)。

源代码上面已经很详细了,我在最后一篇的最后还会发一个工程上来,欢迎大家一起学习!

我也还是学生,写的不好或者有问题的地方还请多多指教~

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。