android view : 自定义
首先,为什么要使用xml来配置view的视图,这个是mvc的一个思想,你可以把前端和数据分离,可以想一下一个及其复杂的视图假如要修改面对复杂的代码是多么的发愁,xml更明了的表达了视图。然而我们知道android中的view有两种形式,代码和xml。但是终究还是代码,只有完整的描绘出view对象。才可以把view完美的显示在手机上,也就是说在view绘制之前,都是把view的xml属性转化为了view对象的属性。这也就是为什么要layout中使用xml布局自定义view的时候要使用两个参数构造函数了。attributeSet attrs 就是你在xml中书写的属性。
明白了这个道理,就说一下android中的自定义view,所谓自定义就是再根据自己的意图去定义view,自定义view有很多种方式,在一些特殊布局的时候可以很轻松的应用,也就是说没有实现不了的视图和手势移动动作,主要就是你要进行一个良好的布局设计,考虑viewgroup的布局方式,view如何显示。还应该知道layout和scrollTo到底是什么意思?
1.自定义属性
首先还是先说怎么自定义属性,我们做的就是模仿android来进行一个xml布局的解析,再设置到自己的代码中来,首先xml中总是有一个xmnls:android这个就是你的属性的报名和名字空间,名称空间可以随便,但是包名一定要准确。这个主要就是要对应你的包内的属性的,也就是说这个是一个xml的约束,属性必须是预先定义的,不能随便书写。自定义的时候就要先自定义属性集合,这个要在values下定义一个attrs.xml文件,使用decare-styleable定义属性集合,这些都要在R文件中生成。里面的属性有name和format成相应的字段值有一个约束。这些东西都是为自定义属性准备的。当你定义好属性集,就可以在布局文件中使用了。对应的android:text = “”的形式,前面的android是名字空间自定义,后面就是属性然后可以跟值,这个有什么用?这个主要是为了你的布局比较复杂,或者是有一些属性希望定义到xml中来但是没有在android中预定义。
接下来,既然定义了属性,我们就要使用,android并不知道我们定义的属性集是什么意思,所以所有属性集拥有的功能都要我们自定来书写,其实这个歌主要是为了某个view大量的使用,为了方便使用。上一节中说过了xml解析的过程,xml解析完之后,把view生成了相应的对象加载到了viewgroup中,其中对象生成的时候使用了两个参数的构造函数,这个构造函数有一个参数attributeset这个里面就是xml中的所有属性,有android的也有自己的,在解析的时候,使用了TypedArray a = context.obtainStyledAttributes(attrs, com.android.internal.R.styleable.View, defStyle, 0);这个就是把attrs的属性转化为了typearray型的对象,这个对象究竟是什么?里面有一个mData数组存放int值,每一个解析到的属性占的是6个位置,也就是每六个元素都是一个属性的描述,我们关注前3个:type,data和resource。可以从AssetManager.STYLE_NUM_ENTRIES = 6等在assetmanager中定义的字段看出来这些概念。然后就是解析了,解析的时候要根据你的R文件中的对应的数组位置来找出你要的属性,这个我认为是设计不好的地方,即使你只用到的属性不多但是还是要申请全部的数组,这里要想理解明白建议看源码。要注意这里解析的是和R.stybleable里面对应的数组,可不是全部,这也就是为什么要定义属性为集合的原因了。前后都是联系的。
我们解析typeedarray就得到了属性的集合元素,这些元素的值就可以拿来用了,这样自定义属性就ok了,其实属性集合就是为了可以从xml中配置view的属性,所以之后做的事情就是view的了,你可以根据xml解析的属性定义多种多样的动作。甚至可以利用属性来配置事件函数等。
2.自定义view
view是viewgroup中的元素,要自定义view其实就是根据要实现的视图来进行修改view,view自定义的时候可以利用已有的view,如textview等,还可以直接继承view,主要关注的就是view绘制流程中onmeasure,onlayout,ondraw这3个函数的回调。根据onmeasure来自判断空间大小,根据onlayout来布局,ondraw来绘制。
3.自定义viewgroup
之所以view如此的简短,我想所有的东西都写到viewgroup中,viewgroup自定义的时候也是有很多的方式,包括自我定义view的两种,还可以利用组合视图,利用include来包括一个布局等。这里要研究是是直接继承viewgroup,viewgroup要重写onmeasure,不仅要测量自己的布局,还要测绘子view的布局。结合一些本地变量,很容易实现linearlayout。再次你要复写onlayout来进行子类的布局,毕竟这才是viewgroup的功能。都是要在这两个方法在中调用子类的实现。
4关于视图移动
我想说着才是关键,明白了是视图移动原理,你才能掌握自定义视图,其实就是两个layout和scrollto这两个方法的使用。layout很自然就是进行布局,scrollto是视图的移动。分析源码我们可以得出layout改变的是view的变量mLeft,mTop等变量这些变量说明的是在距离父view的边的距离。是以父视图为依据的。scrollto是改变的mScrollX,mScrollY。这两个是距离view边界的距离。你要是理解者这两个概念,就理解了视图移动。
说白了,每一个view都是利用viewgrouplayout出来的,之后view的可见的部分就是布局出来的l,r,t,b的之前的区域了。但是view是无穷大的,你要知道。但是viewgroup只给了你一个小窗口让你显示你的内容。而scrollTo改变的就是视图距离这个小窗口的上左边界的距离。这时候又有一个概念,就是视图的canves和视图背景和视图的内容。这3个是不同的概念,参考的坐标也不一样。canves是画布,view背景和view内容是不一样的。
tip:背景是指的一张图片或者是什么,假如没有传递背景,就没有,在测绘的时候很可能会有布局和没有布局是不一样的,就好比一个纯粹的view,没有背景的时候是没有测绘的边界的,在有了背景之后就设置为了背景的测量大小。背景就好比是一个button的边框,但是内容就是button上的字。在绘制view的一节我们看到了canvas.translate(scrollX, scrollY);background.draw(canvas);canvas.translate(-scrollX, -scrollY);这个就是关键,假如你的view移动了,但是背景不会移动,这段代码的意思就是先把canves移动到view移动的地方,然后绘制背景,再把canves移动回去。这样背景还是在原来的view的其实位置,但是你绘制的内容就跑到了mScrollX,mScrollY的偏移处。
了解视图的移动要明白上面的概念,当你使用视图的scrollto的时候你的视图会移动,但是可视的范围还是父类布局的位置的范围内,假如移动出去范围,就看不到的了。就好像父布局遮住了一样。还有一点要注意,就是你在传递值的时候想右下移动应该传递负值。有人就有疑问不是坐标是左上角,向下向右是正方向吗?实际这个是view内容的坐标系,但是绘制图形的时候参考的是canves的坐标系。视图向下移动,相对于canves来说实际上是向上运动。也就是负值。所以所这里绘制的坐标参考系和你的view内容坐标实际上是不一样的。
彻底明白了这个道理之后,就知道了在父布局中的移动需要使用layout,在本布局中的移动需要scrollTo。这也就是我说的为什么任何的移动都是可以的就是要看你怎么布局了,假如你的父布局是整个窗口,那么你的任何view都可以在窗口中移动,假如你view是整个布局,那么你的view的内容在窗口中任何移动都是可以的。
android view : 自定义的更多相关文章
- android view自定义
转载自:http://blog.csdn.net/iispring/article/details/50708044
- Android读取自定义View属性
Android读取自定义View属性 attrs.xml : <?xml version="1.0" encoding="utf-8"?> < ...
- Android 自定义View修炼-Android 实现自定义的卫星式菜单(弧形菜单)View
一.总述 Android 实现卫星式菜单也叫弧形菜单的主要要做的工作如下:1.动画的处理2.自定义ViewGroup来实现卫星式菜单View (1)自定义属性 a. 在attrs.xml中 ...
- Android 自定义View修炼-【2014年最后的分享啦】Android实现自定义刮刮卡效果View
一.简介: 今天是2014年最后一天啦,首先在这里,我祝福大家在新的2015年都一个个的新健康,新收入,新顺利,新如意!!! 上一偏,我介绍了用Xfermode实现自定义圆角和椭圆图片view的博文& ...
- Android自定义View——自定义搜索框(SearchView)
Android自定义View——自定义搜索框(SearchView) http://www.apkbus.com/android-142064-1-1.html
- Android解决自定义View获取不到焦点的情况
引言: 我们在使用Android View或者SurfaceView进行图形绘制,可以绘制各种各样我们喜欢的图形,然后满怀信心的给我们的View加上onTouchEvent.onKeyDown.onK ...
- android开发:Android 中自定义View的应用
大家好我们今天的教程是在Android 教程中自定义View 的学习,对于初学着来说,他们习惯了Android 传统的页面布局方式,如下代码: <?xml version="1.0&q ...
- Android之自定义View学习(一)
Android之自定义View学习(一) Canvas常用方法: 图片来源 /** * Created by SiberiaDante on 2017/6/3. */ public class Bas ...
- android中自定义view构造函数ContentItemView(Context context, AttributeSet paramAttributeSet)的用处
自己定义一个view <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:a ...
随机推荐
- [原创]VM虚拟机Centos6.4网络配置。
关于虚拟机VMware 3种网络模式(桥接.nat.Host-only)的工作原理http://www.cnblogs.com/hehexiaoxia/p/4042583.html 操作环境 主机:W ...
- USE INSTAVPN TO DESPLOY VPN server IN amazon EC2
Requirements Ubuntu 14.04 512 MB RAM Install curl -sS https://raw.githubusercontent.com/sockeye44/in ...
- 一个面试题的解答-----从500(Id不连续)道试题库里随机抽取20道题!
做一个考试系统的项目,现在从试题库里面随机抽取20道题 比如我题库有500道题(ID不连续).题目出现了,如何解决呢,随机抽取! 1,我们先把500道题的id存进一个长度为500的数组. 2,实现代码 ...
- <java基础学习>01环境变量配置
安装完JDK开始配置系统环境变量,在path变量里面添加java的bin目录 方法二: 配置完成后 在命令下输入javac查看是否配置成功 第一个java程序 hello world! class H ...
- iOS 8 以后 MKMapView 代理不执行问题
因为ios8上,如果你使用了mapView,必须设置mapView的大小,必须把它添加显示在视图上. 可以将frame设为(0,0,0.1,0.1)
- C++多线程3
#include "stdafx.h" #include <windows.h> #include <process.h> int g_count; ; u ...
- easyui tabs update后tab上关闭图标失效的解决方案
问题:使用easyui的tabs组件的时候,调用了tab的update方法,更新后的tab标签上的关闭图标失效 使用的js文件是1.3版本的jquery.easyui.min.js文件,通过读源文件发 ...
- HTML5与CSS3经典代码
1)全屏背景 body { background: url(../img/pic.jpg) no-repeat center center fixed; background-size: cover; ...
- Multiple View Geometry in Computer vision 1.1节部分翻译
1.1简介—无处不在的投影几何 我们都熟悉射影变换.当我们看一幅图,我们看到的方形不是方形,或圆形不是圆形.平面立体映射到图片上的变换是一个投影变换的例子. 因此投影变换时保留的几何属性是什么呢?当然 ...
- 你可能不知道的iOS冷知识——#pragma
Mattt Thompson撰写. Zihan Xu翻译. 发布于2012年10月1日 #pragma 声明是彰显 Objective-C 工艺的标志之一.虽然 #pragma 最初的目的是为了使得源 ...