Android提供的控件有时候并不能满足我们的要求 所以我们要开发自己的控件
一些基础知识:
Android view的3个方法
1、measure操作
measure操作主要用于计算视图的大小,即视图的宽度和长度。在view中定义为final类型,要求子类不能修改。measure()函数中又会调用下面的函数:
onMeasure(),视图大小的将在这里最终确定,也就是说measure只是对onMeasure的一个包装,子类可以覆写onMeasure()方法实现自己的计算视图大小的方式,并通过setMeasuredDimension(width, height)保存计算结果。
所以我们在绘制view的时候可以通过这个onMeasure 方法返回这个view的最终大小
2、layout操作
layout操作用于设置视图在屏幕中显示的位置。在view中定义为final类型,要求子类不能修改。layout()函数中有两个基本操作:(1)setFrame(l,t,r,b),l,t,r,b即子视图在父视图中的具体位置,该函数用于将这些参数保存起来;
(2)onLayout(),在View中这个函数什么都不会做,提供该函数主要是为viewGroup类型布局子视图用的;
一般不用修改这个函数
3、draw操作
draw操作利用前两部得到的参数,将视图显示在屏幕上,到这里也就完成了整个的视图绘制工作。子类也不应该修改该方法,因为其内部定义了绘图的基本操作:
(1)绘制背景;
(2)如果要视图显示渐变框,这里会做一些准备工作;
(3)绘制视图本身,即调用onDraw()函数。在view中onDraw()是个空函数,也就是说具体的视图都要覆写该函数来实现自己的显示(比如TextView在这里实现了绘制文字的过程)。而对于ViewGroup则不需要实现该函数,因为作为容器是“没有内容“的,其包含了多个子view,而子View已经实现了自己的绘制方法,因此只需要告诉子view绘制自己就可以了,也就是下面的dispatchDraw()方法;
(4)绘制子视图,即dispatchDraw()函数。在view中这是个空函数,具体的视图不需要实现该方法,它是专门为容器类准备的,也就是容器类必须实现该方法;
(5)如果需要(应用程序调用了setVerticalFadingEdge或者setHorizontalFadingEdge),开始绘制渐变框;
(6)绘制滚动条;
从上面可以看出自定义View需要最少覆写onMeasure()和onDraw()两个方法。
1.最基本的是用几个Android系统已经存在的控件组成我们自己的控件 并且在其中添加我们属性
这个时候要有一个xml文件 里面是你的那些控件的组成 然后在构造函数里面
View.inflate你的布局
然后从attrs里面读取信息:这个详细一点介绍
就是通过XML为View注册属性。与Android提供的标准属性写法一样的说:
1.如何得到TypedArray
context.obtainStyledAttributes(attrs,R.styleable.Demo); //其中Demo是从attrs里面声明的
然后使用还得先定义命名空间
MainActivity的布局文件:先定义命名空间 xmlns:uview="http://schemas.android.com/apk/res/com.example.myimageview2" (com.example.myimageview2为你
在manifest中定义的包名)
然后可以像使用系统的属性一样使用:uview:Oriental="Vertical"
2.继承一个已经存储的Android控件 然后再里面添加自己的东西 这个和之前的那个方法1没什么不同呢
3.完全继承view 然后在里面写自己的东西
首先看看Android的view的结构图
有view和view group:几个布局
view的作用: 提供实际的功能
ViewGroup的作用: 用来装孩子的,管理孩子摆放的位置,大小
然后就是view如何构建了 就是一个view是如何显示出来的
measure layout draw
如果需要自定义控件 就要复写onMesure onLayout onDraw 方法
我们首先来看看view里面的代码 看看它是如何构造的
1.View来实现了3个接口drawable.Callback, KeyEvent.Callback
主要是一些drawable 的和一些点击事件的callback
view的构建主要是用了递归的思想来实现的
2.在draw的时候要注意一些参数
canvas.drawRect(20,20,120,120,paint);
左右都是相对于父控件的左边 上和下都是相对于控件的上
如何实现画Bitmap
Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.mipmap.burning);