自定义view入门
如何自定义控件主要分为以下几个步骤:
1、自定义属性的声明与获取
(1)分析需要的自定义属性
(2)在res/values/attrs.xml定义声明,如
<resources> <declare-styleable name="HookView"> <attr name="loadingText" format="string" /> <attr name="completeText" format="string" /> <attr name="textSize" format="dimension" /> </declare-styleable> </resources>
(3)在layout xml文件中进行使用
定义了名称然后3个属性,然后在自定义控件引用时候加上
xmlns:app="http://schemas.android.com/apk/res-auto"
然后使用app:loadingText = “string”设置所要配置的属性
(4)在view的构造方法中进行获取
在自定义控件中利用TypedArray获取所设置的属性
if (attrs != null) { //获取自定义属性 TypedArray ta = context.obtainStyledAttributes(attrs, R.styleable.HookView); if (ta.hasValue(R.styleable.HookView_loadingText)) loadingText = ta.getString(R.styleable.HookView_loadingText); if (ta.hasValue(R.styleable.HookView_completeText)) completeText = ta.getString(R.styleable.HookView_completeText); textSize = ta.getDimension(R.styleable.HookView_textSize, 20); ta.recycle(); }
这里使用完记得recycle(),这是由于自定义View,会随着 Activity的每一次Create而Create,因此,需要系统频繁的创建array,对内存和性能是一个不小的开销,如果不使用池模式,每次都让GC来回收,很可能就会造成OutOfMemory,程序在运行时维护了一个 TypedArray的池,程序调用时,会向该池中请求一个实例,用完之后,调用 recycle() 方法来释放该实例,从而使其可被其他模块复用,记得使用完调用recycle()就好。
2、测量onMewsure(占多大空间)
通常View在屏幕上显示出来要先经过measure然后到layout. 在调用onMeasure(int widthSpec, int heightSpec)方法时,要涉及到MeasureSpec的使用
MeasureSpec有3种模式分别是【UNSPECIFIED】 、【EXACTLY】、【AT_MOST】
当我们设置width或height为fill_parent时,容器在布局时调用子 view的measure方法传入的模式是EXACTLY,因为子view会占据剩余容器的空间,所以它大小是确定的。
而当设置为 wrap_content时,容器传进去的是AT_MOST, 表示子view的大小最多是多少,这样子view会根据这个上限来设置自己的尺寸。当子view的大小设置为精确值时,容器传入的是EXACTLY, 而MeasureSpec的UNSPECIFIED模式通常是滑动控件中给子控件View的onMeasure方法默认行为是当模式为UNSPECIFIED时,设置尺寸为mMinWidth(通常为0)或者背景drawable的最小尺寸。
形象的说来,onMeasure方法在父元素正要放置该控件时调用.父控件调用它向子控件问一个问题,“你想要用多大地方啊?”,然后传入两个参数——widthMeasureSpec和heightMeasureSpec.它们指明控件可获得的空间以及关于这个空间描述的元数据.比返回一个结果要好的方法是你传递View的高度和宽度到setMeasuredDimension方法里.
下面看一下经典的View中onMeasure实现
@Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { int measuredHeight = measureHeight(heightMeasureSpec); int measuredWidth = measureWidth(widthMeasureSpec); setMeasuredDimension(measuredHeight, measuredWidth); } private int measureHeight(int measureSpec) { int specMode = MeasureSpec.getMode(measureSpec); int specSize = MeasureSpec.getSize(measureSpec); // Default size if no limits are specified. int result = 500; if (specMode == MeasureSpec.AT_MOST){ // Calculate the ideal size of your // control within this maximum size. // If your control fills the available // space return the outer bound. result = specSize; } else if (specMode == MeasureSpec.EXACTLY){ // If your control can fit within these bounds return that value. result = specSize; } return result; } private int measureWidth(int measureSpec) { int specMode = MeasureSpec.getMode(measureSpec); int specSize = MeasureSpec.getSize(measureSpec); // Default size if no limits are specified. int result = 500; if (specMode == MeasureSpec.AT_MOST){ // Calculate the ideal size of your control // within this maximum size. // If your control fills the available space // return the outer bound. result = specSize; } else if (specMode == MeasureSpec.EXACTLY){ // If your control can fit within these bounds return that value. result = specSize; } return result; }
关于MeasureSpec类这里多说一点,
它代表一个32位的int值,高2位代表specMode(测量模式),低30位代表specsize(某种测量模式下的规格大小)
关于它的常用三个函数:
static int getMode(int measureSpec):根据提供的测量值(格式)提取模式(上述三个模式之一)
static int getSize(int measureSpec):根据提供的测量值(格式)提取大小值(这个大小也就是我们通常所说的大小)
static int makeMeasureSpec(int size,int mode):根据提供的大小值和模式创建一个测量值(格式)
3、布局onLayout(放在什么位置)
4、绘制onDraw(绘制什么)
通常需要熟练掌握 canvas、Path的API,可能还有属性动画的交互
5、onTouchEvent
需要做用户交互,对Event事件的捕捉处理
6、onInterceptTouchEvent(viewgroup)
viewgroup中事件拦截,这里需要掌握事件分发机制
入门主要是这几块内容,每一块都需要深入理解,在看到一个自定义view源码时往往就是通过这几块往下分析
自定义view入门的更多相关文章
- Android简易实战教程--第二十七话《自定义View入门案例之开关按钮详细分析》
转载此博客请注明出处点击打开链接 http://blog.csdn.net/qq_32059827/article/details/52444145 对于自定义view,可能是一个比较大的 ...
- Android自定义View入门(一)
最近在写一个关于音乐播放的应用,写到播放界面UI时,就想自己实现的一个播放界面.那么如何实现自定义View呢?通过查看他人博客和Android官方开发文档,初步了解了一些浅显的内容.在此记录,已供需要 ...
- 自定义View入门-绘制基础(1)
### 前言 说道自定义View,我们一定会想到,自定义View的绘制流程 - 测量阶段(measure) - 布局阶段(layout) - 绘制阶段(draw) 我们看到的一些炫酷的view效果,都 ...
- 1.自定义view入门
1.继承自view 系统提供的view 如 TextView .ImageView 都是继承自view的: 2.自定义一个TextView 通过自定义一个TextView 来熟悉继承自view 的自定 ...
- Android之自定义View的实现
对于学习Android开发的小童鞋对于自定义View一定不会陌生,相信大家对它是又爱又恨,爱它可以跟随我们的心意设计出漂亮的效果:恨它想要完全流畅掌握,需要一定的功夫.对于初学者来说确实很不容易,网上 ...
- Android自定义View
转载请标明出处:http://blog.csdn.net/lmj623565791/article/details/24252901 很多的Android入门程序猿来说对于Android自定义View ...
- Android 自定义View (一)
转载请标明出处:http://blog.csdn.net/lmj623565791/article/details/24252901 很多的Android入门程序猿来说对于Android自定义View ...
- Android 自定义View(button)
很多的Android入门程序猿来说对于Android自定义View,可能都是比较恐惧的,但是这又是高手进阶的必经之路,所有准备在自定义View上面花一些功夫,多写一些文章.先总结下自定义View的步骤 ...
- 推翻自己和过往,重学自定义View
http://blog.csdn.net/lfdfhl/article/details/51671038 深入探讨Android异步精髓Handler 站在源码的肩膀上全解Scroller工作机制 A ...
随机推荐
- Android开发学习之路--Android Studio cmake编译ffmpeg
最新的android studio2.2引入了cmake可以很好地实现ndk的编写.这里使用最新的方式,对于以前的android下的ndk编译什么的可以参考之前的文章:Android开发学习之路– ...
- 2016年年终CSDN博客总结
2015年12月1日,结束了4个月的尚观嵌入式培训生涯,经过了几轮重重面试,最终来到了伟易达集团.经过了长达3个月的试用期,正式成为了伟易达集团的助理工程师. 回顾一年来的学习,工作,生活.各种酸甜苦 ...
- Retrofit2.0通俗易懂的学习姿势,Retrofit2.0 + OkHttp3 + Gson + RxJava
Retrofit2.0通俗易懂的学习姿势,Retrofit2.0 + OkHttp3 + Gson + RxJava Retrofit,因为其简单与出色的性能,也是受到很多人的青睐,但是他和以往的通信 ...
- The packages can be overrided by Java Endorsed Standards
Endorsed Standards APIs The Endorsed Standards for Java SE constitute all classes and interfaces ...
- [Vim]vim学习笔记--多个文件打开,切换,关闭
一种情况是在shell中用vim打开多个文件,另一种是在vim编辑器中打开多个文件 同时打开多个文件 vim file1 file2 打开文件并水平窗口显示 vim -o file1 file2 打 ...
- 【酷我天气】完整的天气App项目
本人完全自主设计与开发的一款轻量级简约好用的天气App,无广告,无烦人的通知栏信息,定位精准,天气信息数据准确,还支持更换背景皮肤哦,颜值爆表. 实现的功能: 1自动定位:自动获取用户所在的城市位置然 ...
- Linux网络和进程管理
1) 计算机网络是通过外围的设备和连接,将分布在相同或不同区域的多台计算机 连接在一起所形成的集合.网络中的计算机实现彼此间互相通信,并且可以共 同使用硬件.软件和数据资源,实现资源共享.Lin ...
- 查看apk签名信息
经常在注册开发者的时候会遇到要求填写申请应用的应用签名: 有两种很方便的方法: 1.如果没有源码或者没有打开eclipse,直接下载这个应用应用下载链接 使用截图,只要把包名输入,自动会出现签名信息. ...
- 用API创建用户
DECLARE lc_user_name VARCHAR2(100) := 'PRAJ_TEST'; lc_user_password VARCHAR2(100) := 'Oracle123'; ld ...
- ExtJS学习(一)Ext自定义类实现
工作中项目需要extjs,所以学习一下,做个笔记防止遗忘了.以后回忆起来也方便. 首先下载extjs官网地址:http://extjs.org.cn/ 下载以后的目录结构: 先写一个入门的程序吧自定义 ...