您的位置:首页 > 理论基础 > 计算机网络

Android自定义控件之入门篇---整理网络上的资源

2016-05-22 21:52 477 查看
前言,

我的视频系列 http://edu.csdn.net/course/detail/2741

一起来学习Android…

本篇博客主要是想要讲解一下自定义控件如何入门,其中有好多资料资源来源自网络,综合了网络上一些有些的博文,又同时增加了博主自己的一些思路,在这里姑且以原创自居吧…

如何入手自定义控件

第一步:先判断当前要写的是一个View还是一个ViewGroup

Android的UI界面都是由View和ViewGroup及其派生类组合而成的。其中,View是所有UI组件的基类,而ViewGroup是容纳这些组件的容器,其本身也是从View派生出来的。AndroidUI界面的一般结构可参见下面的示意图:


一般ViewGroup我们可以理解为可以放控件的容器



而View我们可以理解为单一的一个控件



第二步:了解自定义控件常用的一些方法

重要的方法已经加黑标记,初学者掌握先来掌握这四个方法。

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

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

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

measure操作主要用于计算视图的大小,即视图的宽度和长度。在view中定义为final类型,要求子类不能修改。measure()函数中又会调用下面的函数:

(1)onMeasure(),视图大小的将在这里最终确定,也就是说measure只是对onMeasure的一个包装,子类可以覆写onMeasure()方法实现自己的计算视图大小的方式,并通过setMeasuredDimension(width, height)保存计算结果。

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

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

layout操作用于设置视图在屏幕中显示的位置。在view中定义为final类型,要求子类不能修改。layout()函数中有两个基本操作:


(1)setFrame(l,t,r,b),l,t,r,b即子视图在父视图中的具体位置,该函数用于将这些参数保存起来;

(2)onLayout(),在View中这个函数什么都不会做,提供该函数主要是为viewGroup类型布局子视图用的;

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

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

draw操作利用前两部得到的参数,将视图显示在屏幕上,到这里也就完成了整个的视图绘制工作。子类也不应该修改该方法,因为其内部定义了绘图的基本操作:

(1)绘制背景;

(2)如果要视图显示渐变框,这里会做一些准备工作;

(3)绘制视图本身,即调用onDraw()函数。在view中onDraw()是个空函数,也就是说具体的视图都要覆写该函数来实现自己的显示(比如TextView在这里实现了绘制文字的过程)。而对于ViewGroup则不需要实现该函数,因为作为容器是“没有内容“的,其包含了多个子view,而子View已经实现了自己的绘制方法,因此只需要告诉子view绘制自己就可以了,也就是下面的dispatchDraw()方法;

(4)绘制子视图,即dispatchDraw()函数。在view中这是个空函数,具体的视图不需要实现该方法,它是专门为容器类准备的,也就是容器类必须实现该方法;

(5)如果需要(应用程序调用了setVerticalFadingEdge或者setHorizontalFadingEdge),开始绘制渐变框;

(6)绘制滚动条;

从上面可以看出自定义View需要最少覆写onMeasure()和onDraw()两个方法。

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

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

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

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

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

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

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

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

从自定义一个可以随手指滑动的圆圈来进行入手

分析当前控件是应该继承自View还是ViewGroup

由于这个自定义控件内部不需要添加任何的其他控件,所以是继承自View

public class MovingView extends View

分析该控件是否需要进行测量并设置大小

可以在布局文件中设置这个View的宽高直接是匹配父窗体

那么,只需要测量出该圆圈的初始位置即可

@Override

protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {

super.onMeasure(widthMeasureSpec, heightMeasureSpec);

// 测量计算出当前屏幕控件的宽高

width = this.getWidth();

height = this.getHeight();

x = width * 1.0f / 2;

y = height * 1.0f / 2;

}


绘制界面,重写onDraw方法

@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
// 创建画笔
Paint paint = new Paint();
// 设置画笔颜色
paint.setColor(Color.BLUE);
// 画出小球
canvas.drawCircle(x, y, circleR, paint);
}


重写onTouchEvent,让小圆点随手指移动而移动

需要判断当前手指按下的位置,是否是在小球身上

/**
* 计算手指是否是落在了滑块上(默认是按照滑块在未解锁的初始位置来计算的)
*/
public boolean isDownOnBlock(float x1, float x2, float y1, float y2) {
float sqrt = FloatMath.sqrt(Math.abs(x1 - x2) * Math.abs(x1 - x2)
+ Math.abs(y1 - y2) * Math.abs(y1 - y2));
if (sqrt <= circleR) {
return true;
}
return false;
}


onTouchEvent的具体代码

@Override
public boolean onTouchEvent(MotionEvent event) {
float x2 = event.getX();
float y2 = event.getY();
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
downOnBlock = isDownOnBlock(x2, x, y2, y);
break;
case MotionEvent.ACTION_MOVE:
if (downOnBlock) {
x = x2;
y = y2;
postInvalidate();
}
break;
}
//消费该事件
return true;
}


在执行onTouchEvent的时候,重新绘制界面

postInvalidate()

再次执行onDraw方法

@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
// 创建画笔
Paint paint = new Paint();
// 设置画笔颜色
paint.setColor(Color.RED);
// 进行边框判断,设置图标不超过边界
if (x - circleR < 0) {
x = circleR;
}
if (y - circleR < 0) {
y = circleR;
}
if (x > width - circleR) {
x = width - circleR;
}
if (y > height - circleR) {
y = height - circleR;
}
// 画出小球
canvas.drawCircle(x, y, circleR, paint);
}


以上是自定义控件的简单应用,还在修改整理中…
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  android 控件