Android自定义控件之入门篇---整理网络上的资源
2016-05-22 21:52
477 查看
前言,
我的视频系列 http://edu.csdn.net/course/detail/2741,
一起来学习Android…
本篇博客主要是想要讲解一下自定义控件如何入门,其中有好多资料资源来源自网络,综合了网络上一些有些的博文,又同时增加了博主自己的一些思路,在这里姑且以原创自居吧…
一般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及其派生类都具有的方法,重载该类可以在布局发生改变时作定制处理,这在实现一些特效时非常有用。
(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
public class MovingView extends View
分析该控件是否需要进行测量并设置大小
可以在布局文件中设置这个View的宽高直接是匹配父窗体
那么,只需要测量出该圆圈的初始位置即可
绘制界面,重写onDraw方法
重写onTouchEvent,让小圆点随手指移动而移动
需要判断当前手指按下的位置,是否是在小球身上
onTouchEvent的具体代码
在执行onTouchEvent的时候,重新绘制界面
postInvalidate()
再次执行onDraw方法
以上是自定义控件的简单应用,还在修改整理中…
我的视频系列 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); }
以上是自定义控件的简单应用,还在修改整理中…
相关文章推荐
- 使用C++实现JNI接口需要注意的事项
- Android IPC进程间通讯机制
- Android Manifest 用法
- [转载]Activity中ConfigChanges属性的用法
- Android之获取手机上的图片和视频缩略图thumbnails
- Android之使用Http协议实现文件上传功能
- Android学习笔记(二九):嵌入浏览器
- android string.xml文件中的整型和string型代替
- i-jetty环境搭配与编译
- android之定时器AlarmManager
- android wifi 无线调试
- Android Native 绘图方法
- Android java 与 javascript互访(相互调用)的方法例子
- android 代码实现控件之间的间距
- android FragmentPagerAdapter的“标准”配置
- Android"解决"onTouch和onClick的冲突问题
- android:installLocation简析
- android searchView的关闭事件
- SourceProvider.getJniDirectories