开发自定义控件的步骤:
1、了解View的工作原理
2、 编写继承自View的子类
3、 为自定义View类增加属性
4、 绘制控件
5、 响应用户消息
6 、自定义回调函数
一、View结构原理
Android系统的视图结构的设计也采用了组合模式,即View作为所有图形的基类,Viewgroup对View继承扩展为视图容器类。
View定义了绘图的基本操作
基本操作由三个函数完成:measure()、layout()、draw(),其内部又分别包含了onMeasure()、onLayout()、onDraw()三个子方法。具体操作如下:
1、measure操作
measure操作主要用于计算视图的大小,即视图的宽度和长度。在view中定义为final类型,要求子类不能修改。measure()函数中又会调用下面的函数:
(1)onMeasure(),视图大小的将在这里最终确定,也就是说measure只是对onMeasure的一个包装,子类可以覆写onMeasure()方法实现自己的计算视图大小的方式,并通过setMeasuredDimension(width, height)保存计算结果。
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()两个方法。
二、View类的构造方法
创建自定义控件的3种主要实现方式:
1)继承已有的控件来实现自定义控件: 主要是当要实现的控件和已有的控件在很多方面比较类似, 通过对已有控件的扩展来满足要求。
2)通过继承一个布局文件实现自定义控件,一般来说做组合控件时可以通过这个方式来实现。
注意此时不用onDraw方法,在构造广告中通过inflater加载自定义控件的布局文件,再addView(view),自定义控件的图形界面就加载进来了。
3)通过继承view类来实现自定义控件,使用GDI绘制出组件界面,一般无法通过上述两种方式来实现时用该方式。
<code class="hljs vhdl has-numbering" style="display: block; padding: 0px; background-color: transparent; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-top-left-radius: 0px; border-top-right-radius: 0px; border-bottom-right-radius: 0px; border-bottom-left-radius: 0px; word-wrap: normal; background-position: initial initial; background-repeat: initial initial;">View(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">Context</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">context</span>) //Simple constructor <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">to</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">use</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">when</span> creating a view from code. View(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">Context</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">context</span>, AttributeSet attrs) //Constructor that <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">is</span> called <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">when</span> inflating a view from XML. View(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">Context</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">context</span>, AttributeSet attrs, int defStyle) //Perform inflation from XML <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">and</span> apply a class-specific base style.</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; background-color: rgb(238, 238, 238); top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right;"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li></ul>
三、自定义View增加属性的两种方法:
1)在View类中定义。通过构造函数中引入的AttributeSet 去查找XML布局的属性名称,然后找到它对应引用的资源ID去找值。
案例:实现一个带文字的图片(图片、文字是onDraw方法重绘实现)
<code class="hljs java has-numbering" style="display: block; padding: 0px; background-color: transparent; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-top-left-radius: 0px; border-top-right-radius: 0px; border-bottom-right-radius: 0px; border-bottom-left-radius: 0px; word-wrap: normal; background-position: initial initial; background-repeat: initial initial;"><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> <span class="hljs-class" style="box-sizing: border-box;"><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">class</span> <span class="hljs-title" style="box-sizing: border-box; color: rgb(102, 0, 102);">MyView</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">extends</span> <span class="hljs-title" style="box-sizing: border-box; color: rgb(102, 0, 102);">View</span> {</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">private</span> String mtext; <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">private</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> msrc; <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> <span class="hljs-title" style="box-sizing: border-box;">MyView</span>(Context context) { <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">super</span>(context); <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// TODO Auto-generated constructor stub</span> } <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> <span class="hljs-title" style="box-sizing: border-box;">MyView</span>(Context context, AttributeSet attrs) { <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">super</span>(context, attrs); <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// TODO Auto-generated constructor stub</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> resourceId = <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>; <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> textId = attrs.getAttributeResourceValue(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">null</span>, <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"Text"</span>,<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>); <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> srcId = attrs.getAttributeResourceValue(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">null</span>, <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"Src"</span>, <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>); mtext = context.getResources().getText(textId).toString(); msrc = srcId; } <span class="hljs-annotation" style="color: rgb(155, 133, 157); box-sizing: border-box;">@Override</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">protected</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">void</span> <span class="hljs-title" style="box-sizing: border-box;">onDraw</span>(Canvas canvas) { <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// TODO Auto-generated method stub</span> Paint paint = <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">new</span> Paint(); paint.setColor(Color.RED); InputStream is = getResources().openRawResource(msrc); Bitmap mBitmap = BitmapFactory.decodeStream(is); <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> bh = mBitmap.getHeight(); <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> bw = mBitmap.getWidth(); canvas.drawBitmap(mBitmap, <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>,<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>, paint); <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//canvas.drawCircle(40, 90, 15, paint);</span> canvas.drawText(mtext, bw/<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">2</span>, <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">30</span>, paint); } }</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; background-color: rgb(238, 238, 238); top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right;"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li><li style="box-sizing: border-box; padding: 0px 5px;">14</li><li style="box-sizing: border-box; padding: 0px 5px;">15</li><li style="box-sizing: border-box; padding: 0px 5px;">16</li><li style="box-sizing: border-box; padding: 0px 5px;">17</li><li style="box-sizing: border-box; padding: 0px 5px;">18</li><li style="box-sizing: border-box; padding: 0px 5px;">19</li><li style="box-sizing: border-box; padding: 0px 5px;">20</li><li style="box-sizing: border-box; padding: 0px 5px;">21</li><li style="box-sizing: border-box; padding: 0px 5px;">22</li><li style="box-sizing: border-box; padding: 0px 5px;">23</li><li style="box-sizing: border-box; padding: 0px 5px;">24</li><li style="box-sizing: border-box; padding: 0px 5px;">25</li><li style="box-sizing: border-box; padding: 0px 5px;">26</li><li style="box-sizing: border-box; padding: 0px 5px;">27</li><li style="box-sizing: border-box; padding: 0px 5px;">28</li><li style="box-sizing: border-box; padding: 0px 5px;">29</li><li style="box-sizing: border-box; padding: 0px 5px;">30</li><li style="box-sizing: border-box; padding: 0px 5px;">31</li><li style="box-sizing: border-box; padding: 0px 5px;">32</li><li style="box-sizing: border-box; padding: 0px 5px;">33</li><li style="box-sizing: border-box; padding: 0px 5px;">34</li><li style="box-sizing: border-box; padding: 0px 5px;">35</li><li style="box-sizing: border-box; padding: 0px 5px;">36</li><li style="box-sizing: border-box; padding: 0px 5px;">37</li><li style="box-sizing: border-box; padding: 0px 5px;">38</li><li style="box-sizing: border-box; padding: 0px 5px;">39</li><li style="box-sizing: border-box; padding: 0px 5px;">40</li><li style="box-sizing: border-box; padding: 0px 5px;">41</li><li style="box-sizing: border-box; padding: 0px 5px;">42</li><li style="box-sizing: border-box; padding: 0px 5px;">43</li><li style="box-sizing: border-box; padding: 0px 5px;">44</li><li style="box-sizing: border-box; padding: 0px 5px;">45</li></ul>
布局文件:
<code class="hljs xml has-numbering" style="display: block; padding: 0px; background-color: transparent; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-top-left-radius: 0px; border-top-right-radius: 0px; border-bottom-right-radius: 0px; border-bottom-left-radius: 0px; word-wrap: normal; background-position: initial initial; background-repeat: initial initial;"><span class="hljs-pi" style="color: rgb(0, 102, 102); box-sizing: border-box;"><?xml version="1.0" encoding="utf-8"?></span> <span class="hljs-tag" style="color: rgb(0, 102, 102); box-sizing: border-box;"><<span class="hljs-title" style="box-sizing: border-box; color: rgb(0, 0, 136);">LinearLayout</span> <span class="hljs-attribute" style="box-sizing: border-box; color: rgb(102, 0, 102);">xmlns:android</span>=<span class="hljs-value" style="box-sizing: border-box; color: rgb(0, 136, 0);">"http://schemas.android.com/apk/res/android"</span> <span class="hljs-attribute" style="box-sizing: border-box; color: rgb(102, 0, 102);">android:layout_width</span>=<span class="hljs-value" style="box-sizing: border-box; color: rgb(0, 136, 0);">"match_parent"</span> <span class="hljs-attribute" style="box-sizing: border-box; color: rgb(102, 0, 102);">android:layout_height</span>=<span class="hljs-value" style="box-sizing: border-box; color: rgb(0, 136, 0);">"match_parent"</span> <span class="hljs-attribute" style="box-sizing: border-box; color: rgb(102, 0, 102);">android:orientation</span>=<span class="hljs-value" style="box-sizing: border-box; color: rgb(0, 136, 0);">"vertical"</span> ></span> <span class="hljs-tag" style="color: rgb(0, 102, 102); box-sizing: border-box;"><<span class="hljs-title" style="box-sizing: border-box; color: rgb(0, 0, 136);">com.example.myimageview2.MyView </span> <span class="hljs-attribute" style="box-sizing: border-box; color: rgb(102, 0, 102);">android:id</span>=<span class="hljs-value" style="box-sizing: border-box; color: rgb(0, 136, 0);">"@+id/myView1"</span> <span class="hljs-attribute" style="box-sizing: border-box; color: rgb(102, 0, 102);">android:layout_width</span>=<span class="hljs-value" style="box-sizing: border-box; color: rgb(0, 136, 0);">"wrap_content"</span> <span class="hljs-attribute" style="box-sizing: border-box; color: rgb(102, 0, 102);">android:layout_height</span>=<span class="hljs-value" style="box-sizing: border-box; color: rgb(0, 136, 0);">"wrap_content"</span> <span class="hljs-attribute" style="box-sizing: border-box; color: rgb(102, 0, 102);">Text</span>=<span class="hljs-value" style="box-sizing: border-box; color: rgb(0, 136, 0);">"@string/hello_world"</span> <span class="hljs-attribute" style="box-sizing: border-box; color: rgb(102, 0, 102);">Src</span>=<span class="hljs-value" style="box-sizing: border-box; color: rgb(0, 136, 0);">"@drawable/xh"</span>/></span> <span class="hljs-tag" style="color: rgb(0, 102, 102); box-sizing: border-box;"></<span class="hljs-title" style="box-sizing: border-box; color: rgb(0, 0, 136);">LinearLayout</span>></span></code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; background-color: rgb(238, 238, 238); top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right;"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li><li style="box-sizing: border-box; padding: 0px 5px;">14</li></ul>
属性Text, Src在自定义View类的构造方法中读取。
2)通过XML为View注册属性。与Android提供的标准属性写法一样。
案例: 实现一个带文字说明的ImageView (ImageView+TextView组合,文字说明,可在布局文件中设置位置)
<code class="hljs java has-numbering" style="display: block; padding: 0px; background-color: transparent; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-top-left-radius: 0px; border-top-right-radius: 0px; border-bottom-right-radius: 0px; border-bottom-left-radius: 0px; word-wrap: normal; background-position: initial initial; background-repeat: initial initial;"><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> <span class="hljs-class" style="box-sizing: border-box;"><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">class</span> <span class="hljs-title" style="box-sizing: border-box; color: rgb(102, 0, 102);">MyImageView</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">extends</span> <span class="hljs-title" style="box-sizing: border-box; color: rgb(102, 0, 102);">LinearLayout</span> {</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> <span class="hljs-title" style="box-sizing: border-box;">MyImageView</span>(Context context) { <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">super</span>(context); <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// TODO Auto-generated constructor stub</span> } <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> <span class="hljs-title" style="box-sizing: border-box;">MyImageView</span>(Context context, AttributeSet attrs) { <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">super</span>(context, attrs); <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// TODO Auto-generated constructor stub</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> resourceId = -<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span>; TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.MyImageView); ImageView iv = <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">new</span> ImageView(context); TextView tv = <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">new</span> TextView(context); <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> N = typedArray.getIndexCount(); <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">for</span> (<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> i = <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>; i < N; i++) { <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> attr = typedArray.getIndex(i); <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">switch</span> (attr) { <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">case</span> R.styleable.MyImageView_Oriental: resourceId = typedArray.getInt( R.styleable.MyImageView_Oriental, <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>); <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">this</span>.setOrientation(resourceId == <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span> ? LinearLayout.HORIZONTAL : LinearLayout.VERTICAL); <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">break</span>; <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">case</span> R.styleable.MyImageView_Text: resourceId = typedArray.getResourceId( R.styleable.MyImageView_Text, <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>); tv.setText(resourceId > <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span> ? typedArray.getResources().getText( resourceId) : typedArray .getString(R.styleable.MyImageView_Text)); <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">break</span>; <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">case</span> R.styleable.MyImageView_Src: resourceId = typedArray.getResourceId( R.styleable.MyImageView_Src, <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>); iv.setImageResource(resourceId > <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span> ?resourceId:R.drawable.ic_launcher); <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">break</span>; } } addView(iv); addView(tv); typedArray.recycle(); } }</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; background-color: rgb(238, 238, 238); top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right;"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li><li style="box-sizing: border-box; padding: 0px 5px;">14</li><li style="box-sizing: border-box; padding: 0px 5px;">15</li><li style="box-sizing: border-box; padding: 0px 5px;">16</li><li style="box-sizing: border-box; padding: 0px 5px;">17</li><li style="box-sizing: border-box; padding: 0px 5px;">18</li><li style="box-sizing: border-box; padding: 0px 5px;">19</li><li style="box-sizing: border-box; padding: 0px 5px;">20</li><li style="box-sizing: border-box; padding: 0px 5px;">21</li><li style="box-sizing: border-box; padding: 0px 5px;">22</li><li style="box-sizing: border-box; padding: 0px 5px;">23</li><li style="box-sizing: border-box; padding: 0px 5px;">24</li><li style="box-sizing: border-box; padding: 0px 5px;">25</li><li style="box-sizing: border-box; padding: 0px 5px;">26</li><li style="box-sizing: border-box; padding: 0px 5px;">27</li><li style="box-sizing: border-box; padding: 0px 5px;">28</li><li style="box-sizing: border-box; padding: 0px 5px;">29</li><li style="box-sizing: border-box; padding: 0px 5px;">30</li><li style="box-sizing: border-box; padding: 0px 5px;">31</li><li style="box-sizing: border-box; padding: 0px 5px;">32</li><li style="box-sizing: border-box; padding: 0px 5px;">33</li><li style="box-sizing: border-box; padding: 0px 5px;">34</li><li style="box-sizing: border-box; padding: 0px 5px;">35</li><li style="box-sizing: border-box; padding: 0px 5px;">36</li><li style="box-sizing: border-box; padding: 0px 5px;">37</li><li style="box-sizing: border-box; padding: 0px 5px;">38</li><li style="box-sizing: border-box; padding: 0px 5px;">39</li><li style="box-sizing: border-box; padding: 0px 5px;">40</li><li style="box-sizing: border-box; padding: 0px 5px;">41</li><li style="box-sizing: border-box; padding: 0px 5px;">42</li><li style="box-sizing: border-box; padding: 0px 5px;">43</li><li style="box-sizing: border-box; padding: 0px 5px;">44</li><li style="box-sizing: border-box; padding: 0px 5px;">45</li></ul>
attrs.xml进行属性声明, 文件放在values目录下
<code class="hljs xml has-numbering" style="display: block; padding: 0px; background-color: transparent; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-top-left-radius: 0px; border-top-right-radius: 0px; border-bottom-right-radius: 0px; border-bottom-left-radius: 0px; word-wrap: normal; background-position: initial initial; background-repeat: initial initial;"><span class="hljs-pi" style="color: rgb(0, 102, 102); box-sizing: border-box;"><?xml version="1.0" encoding="utf-8"?></span> <span class="hljs-tag" style="color: rgb(0, 102, 102); box-sizing: border-box;"><<span class="hljs-title" style="box-sizing: border-box; color: rgb(0, 0, 136);">resources</span>></span> <span class="hljs-tag" style="color: rgb(0, 102, 102); box-sizing: border-box;"><<span class="hljs-title" style="box-sizing: border-box; color: rgb(0, 0, 136);">declare-styleable</span> <span class="hljs-attribute" style="box-sizing: border-box; color: rgb(102, 0, 102);">name</span>=<span class="hljs-value" style="box-sizing: border-box; color: rgb(0, 136, 0);">"MyImageView"</span>></span> <span class="hljs-tag" style="color: rgb(0, 102, 102); box-sizing: border-box;"><<span class="hljs-title" style="box-sizing: border-box; color: rgb(0, 0, 136);">attr</span> <span class="hljs-attribute" style="box-sizing: border-box; color: rgb(102, 0, 102);">name</span>=<span class="hljs-value" style="box-sizing: border-box; color: rgb(0, 136, 0);">"Text"</span> <span class="hljs-attribute" style="box-sizing: border-box; color: rgb(102, 0, 102);">format</span>=<span class="hljs-value" style="box-sizing: border-box; color: rgb(0, 136, 0);">"reference|string"</span>></span><span class="hljs-tag" style="color: rgb(0, 102, 102); box-sizing: border-box;"></<span class="hljs-title" style="box-sizing: border-box; color: rgb(0, 0, 136);">attr</span>></span> <span class="hljs-tag" style="color: rgb(0, 102, 102); box-sizing: border-box;"><<span class="hljs-title" style="box-sizing: border-box; color: rgb(0, 0, 136);">attr</span> <span class="hljs-attribute" style="box-sizing: border-box; color: rgb(102, 0, 102);">name</span>=<span class="hljs-value" style="box-sizing: border-box; color: rgb(0, 136, 0);">"Oriental"</span> ></span> <span class="hljs-tag" style="color: rgb(0, 102, 102); box-sizing: border-box;"><<span class="hljs-title" style="box-sizing: border-box; color: rgb(0, 0, 136);">enum</span> <span class="hljs-attribute" style="box-sizing: border-box; color: rgb(102, 0, 102);">name</span>=<span class="hljs-value" style="box-sizing: border-box; color: rgb(0, 136, 0);">"Horizontal"</span> <span class="hljs-attribute" style="box-sizing: border-box; color: rgb(102, 0, 102);">value</span>=<span class="hljs-value" style="box-sizing: border-box; color: rgb(0, 136, 0);">"1"</span>></span><span class="hljs-tag" style="color: rgb(0, 102, 102); box-sizing: border-box;"></<span class="hljs-title" style="box-sizing: border-box; color: rgb(0, 0, 136);">enum</span>></span> <span class="hljs-tag" style="color: rgb(0, 102, 102); box-sizing: border-box;"><<span class="hljs-title" style="box-sizing: border-box; color: rgb(0, 0, 136);">enum</span> <span class="hljs-attribute" style="box-sizing: border-box; color: rgb(102, 0, 102);">name</span>=<span class="hljs-value" style="box-sizing: border-box; color: rgb(0, 136, 0);">"Vertical"</span> <span class="hljs-attribute" style="box-sizing: border-box; color: rgb(102, 0, 102);">value</span>=<span class="hljs-value" style="box-sizing: border-box; color: rgb(0, 136, 0);">"0"</span>></span><span class="hljs-tag" style="color: rgb(0, 102, 102); box-sizing: border-box;"></<span class="hljs-title" style="box-sizing: border-box; color: rgb(0, 0, 136);">enum</span>></span> <span class="hljs-tag" style="color: rgb(0, 102, 102); box-sizing: border-box;"></<span class="hljs-title" style="box-sizing: border-box; color: rgb(0, 0, 136);">attr</span>></span> <span class="hljs-tag" style="color: rgb(0, 102, 102); box-sizing: border-box;"><<span class="hljs-title" style="box-sizing: border-box; color: rgb(0, 0, 136);">attr</span> <span class="hljs-attribute" style="box-sizing: border-box; color: rgb(102, 0, 102);">name</span>=<span class="hljs-value" style="box-sizing: border-box; color: rgb(0, 136, 0);">"Src"</span> <span class="hljs-attribute" style="box-sizing: border-box; color: rgb(102, 0, 102);">format</span>=<span class="hljs-value" style="box-sizing: border-box; color: rgb(0, 136, 0);">"reference|integer"</span>></span><span class="hljs-tag" style="color: rgb(0, 102, 102); box-sizing: border-box;"></<span class="hljs-title" style="box-sizing: border-box; color: rgb(0, 0, 136);">attr</span>></span> <span class="hljs-tag" style="color: rgb(0, 102, 102); box-sizing: border-box;"></<span class="hljs-title" style="box-sizing: border-box; color: rgb(0, 0, 136);">declare-styleable</span>></span> <span class="hljs-tag" style="color: rgb(0, 102, 102); box-sizing: border-box;"></<span class="hljs-title" style="box-sizing: border-box; color: rgb(0, 0, 136);">resources</span>></span></code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; background-color: rgb(238, 238, 238); top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right;"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li></ul>
MainActivity的布局文件:先定义命名空间
<code class="hljs avrasm has-numbering" style="display: block; padding: 0px; background-color: transparent; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-top-left-radius: 0px; border-top-right-radius: 0px; border-bottom-right-radius: 0px; border-bottom-left-radius: 0px; word-wrap: normal; background-position: initial initial; background-repeat: initial initial;"><span class="hljs-label" style="box-sizing: border-box;">xmlns:</span>uview=<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"http://schemas.android.com/apk/res/com.example.myimageview2"</span></code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; background-color: rgb(238, 238, 238); top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right;"><li style="box-sizing: border-box; padding: 0px 5px;">1</li></ul>
然后可以像使用系统的属性一样使用:uview:Oriental=”Vertical”
<code class="hljs avrasm has-numbering" style="display: block; padding: 0px; background-color: transparent; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-top-left-radius: 0px; border-top-right-radius: 0px; border-bottom-right-radius: 0px; border-bottom-left-radius: 0px; word-wrap: normal; background-position: initial initial; background-repeat: initial initial;"><LinearLayout xmlns:android=<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"http://schemas.android.com/apk/res/android"</span> xmlns:uview=<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"http://schemas.android.com/apk/res/com.example.myimageview2"</span> xmlns:tools=<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"http://schemas.android.com/tools"</span> android:layout_width=<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"match_parent"</span> android:layout_height=<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"match_parent"</span> android:orientation=<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"vertical"</span> tools:context=<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">".MainActivity"</span> > <TextView android:layout_width=<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"wrap_content"</span> android:layout_height=<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"wrap_content"</span> android:text=<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"@string/hello_world"</span> /> <<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">com</span><span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.example</span><span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.myimageview</span>2<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.MyImageView</span> android:id=<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"@+id/myImageView1"</span> android:layout_width=<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"wrap_content"</span> android:layout_height=<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"wrap_content"</span> uview:Text=<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"这是一个图片说明"</span> uview:Src=<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"@drawable/tw"</span> uview:Oriental=<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"Vertical"</span>> </<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">com</span><span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.example</span><span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.myimageview</span>2<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.MyImageView</span>> </LinearLayout></code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; background-color: rgb(238, 238, 238); top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right;"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li><li style="box-sizing: border-box; padding: 0px 5px;">14</li><li style="box-sizing: border-box; padding: 0px 5px;">15</li><li style="box-sizing: border-box; padding: 0px 5px;">16</li><li style="box-sizing: border-box; padding: 0px 5px;">17</li><li style="box-sizing: border-box; padding: 0px 5px;">18</li><li style="box-sizing: border-box; padding: 0px 5px;">19</li><li style="box-sizing: border-box; padding: 0px 5px;">20</li><li style="box-sizing: border-box; padding: 0px 5px;">21</li><li style="box-sizing: border-box; padding: 0px 5px;">22</li><li style="box-sizing: border-box; padding: 0px 5px;">23</li></ul>
四、控件绘制 onDraw()
五、
六、自定义View的方法
onFinishInflate() 回调方法,当应用从XML加载该组件并用它构建界面之后调用的方法
onMeasure() 检测View组件及其子组件的大小
onLayout() 当该组件需要分配其子组件的位置、大小时
onSizeChange() 当该组件的大小被改变时
onDraw() 当组件将要绘制它的内容时
onKeyDown 当按下某个键盘时
onKeyUp 当松开某个键盘时
onTrackballEvent 当发生轨迹球事件时
onTouchEvent 当发生触屏事件时
onWindowFocusChanged(boolean) 当该组件得到、失去焦点时
onAtrrachedToWindow() 当把该组件放入到某个窗口时
onDetachedFromWindow() 当把该组件从某个窗口上分离时触发的方法
onWindowVisibilityChanged(int): 当包含该组件的窗口的可见性发生改变时触发的方法