1 <div class="line number2 index1 alt1">
2
</div>
<div class="line number3 index2 alt2">
3
</div>
<div class="line number4 index3 alt1">
4
</div>
<div class="line number5 index4 alt2">
5
</div>
<div class="line number6 index5 alt1">
6
</div>
<div class="line number7 index6 alt2">
7
</div>
<div class="line number8 index7 alt1">
8
</div>
<div class="line number9 index8 alt2">
9
</div>
<div class="line number10 index9 alt1">
10
</div>
<div class="line number11 index10 alt2">
11
</div>
<div class="line number12 index11 alt1">
12
</div>
<div class="line number13 index12 alt2">
13
</div>
</td>
<td class="code">
<div class="container">
<div class="line number1 index0 alt2">
`<LinearLayout xmlns:android=``"http://schemas.android.com/apk/res/android"`
</div>
<div class="line number2 index1 alt1">
` ``xmlns:tools=``"http://schemas.android.com/tools"`
</div>
<div class="line number3 index2 alt2">
` ``android:layout_width=``"match_parent"`
</div>
<div class="line number4 index3 alt1">
` ``android:layout_height=``"match_parent"`
</div>
<div class="line number5 index4 alt2">
` ``android:orientation=``"vertical"``>`
</div>
<div class="line number6 index5 alt1">
</div>
<div class="line number7 index6 alt2">
` ``<com.titcktick.customview.CustomView`
</div>
<div class="line number8 index7 alt1">
` ``android:layout_width=``"match_parent"`
</div>
<div class="line number9 index8 alt2">
` ``android:layout_height=``"match_parent"`
</div>
<div class="line number10 index9 alt1">
` ``android:layout_margin=``"10dp"`
</div>
<div class="line number11 index10 alt2">
` ``android:background=``"@android:color/black"``/>`
</div>
<div class="line number12 index11 alt1">
</div>
<div class="line number13 index12 alt2">
`</LinearLayout>`
</div>
</div>
</td>
</tr>
</table>
这里加了10dp的margin并且把View的背景设置为了黑色,是为了方便辨别我们的CustomView,效果如下: 
我们可以看到,默认情况下,如果父控件和CustomView都使用match_parent,则CustomView会充满父控件。 2. 父控件使用match_parent,CustomView使用wrap_content 把layout文件中,CustomView的layout_width/layout_height替换为wrap_content,你会发现,结果依然是充满父控件。 3. 父控件使用match_parent,CustomView使用固定的值 把layout文件中,CustomView的layout_width/layout_height替换为50dp,你会发现,CustomView的显示结果为50dpx50dp,如图所示: 
4. 父控件使用固定的值,CustomView使用match_parent或者wrap_content 那么,如果把父控件的layout_width/layout_height替换为50dp,CustomView设置为match_parent或者wrap_content,你会发现,CustomView的显示结果也是为50dpx50 dp。 5 结论 如果自定义的CustomView采用默认的onMeasure函数,行为如下: (1) CustomView设置为 match_parent 或者 wrap_content 没有任何区别,其显示大小由父控件决定,它会填充满整个父控件的空间。 (2) CustomView设置为固定的值,则其显示大小为该设定的值。 如果你的自定义控件的大小计算就是跟系统默认的行为一致的话,那么你就不需要重写onMeasure函数了。 6. 怎样编写onMeasure函数 系统默认的onMeasure函数的行为就讨论到这,下面也说说怎样重写onMeasure函数,以及onMeasure函数的基本原理,关键部分在代码中以注释的形式给出了,仅供参考: 1 <div class="line number2 index1 alt1">
2
</div>
<div class="line number3 index2 alt2">
3
</div>
<div class="line number4 index3 alt1">
4
</div>
<div class="line number5 index4 alt2">
5
</div>
<div class="line number6 index5 alt1">
6
</div>
<div class="line number7 index6 alt2">
7
</div>
<div class="line number8 index7 alt1">
8
</div>
<div class="line number9 index8 alt2">
9
</div>
<div class="line number10 index9 alt1">
10
</div>
<div class="line number11 index10 alt2">
11
</div>
<div class="line number12 index11 alt1">
12
</div>
<div class="line number13 index12 alt2">
13
</div>
<div class="line number14 index13 alt1">
14
</div>
<div class="line number15 index14 alt2">
15
</div>
<div class="line number16 index15 alt1">
16
</div>
<div class="line number17 index16 alt2">
17
</div>
<div class="line number18 index17 alt1">
18
</div>
<div class="line number19 index18 alt2">
19
</div>
<div class="line number20 index19 alt1">
20
</div>
<div class="line number21 index20 alt2">
21
</div>
<div class="line number22 index21 alt1">
22
</div>
<div class="line number23 index22 alt2">
23
</div>
<div class="line number24 index23 alt1">
24
</div>
<div class="line number25 index24 alt2">
25
</div>
<div class="line number26 index25 alt1">
26
</div>
<div class="line number27 index26 alt2">
27
</div>
<div class="line number28 index27 alt1">
28
</div>
<div class="line number29 index28 alt2">
29
</div>
<div class="line number30 index29 alt1">
30
</div>
<div class="line number31 index30 alt2">
31
</div>
<div class="line number32 index31 alt1">
32
</div>
<div class="line number33 index32 alt2">
33
</div>
<div class="line number34 index33 alt1">
34
</div>
<div class="line number35 index34 alt2">
35
</div>
<div class="line number36 index35 alt1">
36
</div>
<div class="line number37 index36 alt2">
37
</div>
<div class="line number38 index37 alt1">
38
</div>
<div class="line number39 index38 alt2">
39
</div>
<div class="line number40 index39 alt1">
40
</div>
<div class="line number41 index40 alt2">
41
</div>
<div class="line number42 index41 alt1">
42
</div>
<div class="line number43 index42 alt2">
43
</div>
<div class="line number44 index43 alt1">
44
</div>
<div class="line number45 index44 alt2">
45
</div>
<div class="line number46 index45 alt1">
46
</div>
<div class="line number47 index46 alt2">
47
</div>
<div class="line number48 index47 alt1">
48
</div>
<div class="line number49 index48 alt2">
49
</div>
<div class="line number50 index49 alt1">
50
</div>
<div class="line number51 index50 alt2">
51
</div>
<div class="line number52 index51 alt1">
52
</div>
<div class="line number53 index52 alt2">
53
</div>
<div class="line number54 index53 alt1">
54
</div>
</td>
<td class="code">
<div class="container">
<div class="line number1 index0 alt2">
`package` `com.titcktick.customview;`
</div>
<div class="line number2 index1 alt1">
</div>
<div class="line number3 index2 alt2">
`import` `android.content.Context;`
</div>
<div class="line number4 index3 alt1">
`import` `android.util.AttributeSet;`
</div>
<div class="line number5 index4 alt2">
`import` `android.view.View;`
</div>
<div class="line number6 index5 alt1">
</div>
<div class="line number7 index6 alt2">
`public` `class` `CustomView ``extends` `View {`
</div>
<div class="line number8 index7 alt1">
` `
</div>
<div class="line number9 index8 alt2">
` ``private` `static` `final` `int` `DEFAULT_VIEW_WIDTH = ``100``;`
</div>
<div class="line number10 index9 alt1">
` ``private` `static` `final` `int` `DEFAULT_VIEW_HEIGHT = ``100``;`
</div>
<div class="line number11 index10 alt2">
` `
</div>
<div class="line number12 index11 alt1">
` ``public` `CustomView(Context context) {`
</div>
<div class="line number13 index12 alt2">
` ``super``(context); `
</div>
<div class="line number14 index13 alt1">
` ``}`
</div>
<div class="line number15 index14 alt2">
</div>
<div class="line number16 index15 alt1">
` ``public` `CustomView(Context context, AttributeSet attrs) {`
</div>
<div class="line number17 index16 alt2">
` ``super``(context, attrs); `
</div>
<div class="line number18 index17 alt1">
` ``}`
</div>
<div class="line number19 index18 alt2">
` `
</div>
<div class="line number20 index19 alt1">
` ``@Override`
</div>
<div class="line number21 index20 alt2">
` ``protected` `void` `onMeasure(``int` `widthMeasureSpec, ``int` `heightMeasureSpec) {`
</div>
<div class="line number22 index21 alt1">
` `
</div>
<div class="line number23 index22 alt2">
` ``int` `width = measureDimension(DEFAULT_VIEW_WIDTH, widthMeasureSpec);`
</div>
<div class="line number24 index23 alt1">
` ``int` `height = measureDimension(DEFAULT_VIEW_HEIGHT, heightMeasureSpec);`
</div>
<div class="line number25 index24 alt2">
` `
</div>
<div class="line number26 index25 alt1">
` ``setMeasuredDimension(width, height); `
</div>
<div class="line number27 index26 alt2">
` ``}`
</div>
<div class="line number28 index27 alt1">
` `
</div>
<div class="line number29 index28 alt2">
` ``protected` `int` `measureDimension( ``int` `defaultSize, ``int` `measureSpec ) {`
</div>
<div class="line number30 index29 alt1">
` `
</div>
<div class="line number31 index30 alt2">
` ``int` `result = defaultSize;`
</div>
<div class="line number32 index31 alt1">
` `
</div>
<div class="line number33 index32 alt2">
` ``int` `specMode = MeasureSpec.getMode(measureSpec);`
</div>
<div class="line number34 index33 alt1">
` ``int` `specSize = MeasureSpec.getSize(measureSpec);`
</div>
<div class="line number35 index34 alt2">
` `
</div>
<div class="line number36 index35 alt1">
` ``//1. layout给出了确定的值,比如:100dp`
</div>
<div class="line number37 index36 alt2">
` ``//2. layout使用的是match_parent,但父控件的size已经可以确定了,比如设置的是具体的值或者match_parent`
</div>
<div class="line number38 index37 alt1">
` ``if` `(specMode == MeasureSpec.EXACTLY) { `
</div>
<div class="line number39 index38 alt2">
` ``result = specSize; ``//建议:result直接使用确定值`
</div>
<div class="line number40 index39 alt1">
` ``} `
</div>
<div class="line number41 index40 alt2">
` ``//1. layout使用的是wrap_content`
</div>
<div class="line number42 index41 alt1">
` ``//2. layout使用的是match_parent,但父控件使用的是确定的值或者wrap_content`
</div>
<div class="line number43 index42 alt2">
` ``else` `if` `(specMode == MeasureSpec.AT_MOST) { `
</div>
<div class="line number44 index43 alt1">
` ``result = Math.min(defaultSize, specSize); ``//建议:result不能大于specSize`
</div>
<div class="line number45 index44 alt2">
` ``} `
</div>
<div class="line number46 index45 alt1">
` ``//UNSPECIFIED,没有任何限制,所以可以设置任何大小`
</div>
<div class="line number47 index46 alt2">
` ``//多半出现在自定义的父控件的情况下,期望由自控件自行决定大小`
</div>
<div class="line number48 index47 alt1">
` ``else` `{ `
</div>
<div class="line number49 index48 alt2">
` ``result = defaultSize; `
</div>
<div class="line number50 index49 alt1">
` ``}`
</div>
<div class="line number51 index50 alt2">
` `
</div>
<div class="line number52 index51 alt1">
` ``return` `result;`
</div>
<div class="line number53 index52 alt2">
` ``}`
</div>
<div class="line number54 index53 alt1">
`}`
</div>
</div>
</td>
</tr>
</table>
这样重载了onMeasure函数之后,你会发现,当CustomView使用match_parent的时候,它会占满整个父控件,而当CustomView使用wrap_content的时候,它的大小则是代码中定义的默认大小100×100像素。当然,你也可以根据自己的需求改写measureDimension()的实现。 转自:http://ticktick.blog.51cto.com/823160/1540134
|
|
💬 评论