一、概述: 在日常的app使用中,我们会在android 的app中看见 热门标签等自动换行的流式布局,今天,我们就来看看如何
自定义一个类似热门标签那样的流式布局吧(源码下载在下面最后给出)
类似的自定义布局。下面我们就来详细介绍流式布局的应用特点以及用的的技术点:
1.流式布局的特点以及应用场景 特点:当上面一行的空间不够容纳新的TextView时候, 才开辟下一行的空间
原理图:

场景:主要用于关键词搜索或者热门标签等场景 2.自定义ViewGroup,重点重写下面两个方法
1、onMeasure:测量子view的宽高,设置自己的宽和高
2、onLayout:设置子view的位置
onMeasure:根据子view的布局文件中属性,来为子view设置测量模式和测量值 测量=测量模式+测量值;
测量模式有3种: EXACTLY:表示设置了精确的值,一般当childView设置其宽、高为精确值、match_parent时,ViewGroup会将其设置为EXACTLY; AT_MOST:表示子布局被限制在一个最大值内,一般当childView设置其宽、高为wrap_content时,ViewGroup会将其设置为AT_MOST; UNSPECIFIED:表示子布局想要多大就多大,一般出现在AadapterView的item的heightMode中、ScrollView的childView的heightMode中;此种模式比较少见。 3.LayoutParams ViewGroup LayoutParams :每个 ViewGroup 对应一个 LayoutParams; 即 ViewGroup -> LayoutParams getLayoutParams 不知道转为哪个对应的LayoutParams ,其实很简单,就是如下: 子View.getLayoutParams 得到的LayoutParams对应的就是 子View所在的父控件的LayoutParams; 例如,LinearLayout 里面的子view.getLayoutParams ->LinearLayout.LayoutParams 所以 咱们的FlowLayout 也需要一个LayoutParams,由于上面的效果图是子View的 margin, 所以应该使用MarginLayoutParams。即FlowLayout->MarginLayoutParams
4.最后来看看实现的最终效果图:

二、热门标签的流式布局的实现:
1. 自定义热门标签的ViewGroup实现
根据上面的技术分析,自定义类继承于ViewGroup,并重写 onMeasure和onLayout等方法。具体实现代码如下:
<table border="0" cellspacing="0" cellpadding="0">
<tr>
<td class="gutter">
<div class="line number1 index0 alt2">
001
</div>
<div class="line number2 index1 alt1">
002
</div>
<div class="line number3 index2 alt2">
003
</div>
<div class="line number4 index3 alt1">
004
</div>
<div class="line number5 index4 alt2">
005
</div>
<div class="line number6 index5 alt1">
006
</div>
<div class="line number7 index6 alt2">
007
</div>
<div class="line number8 index7 alt1">
008
</div>
<div class="line number9 index8 alt2">
009
</div>
<div class="line number10 index9 alt1">
010
</div>
<div class="line number11 index10 alt2">
011
</div>
<div class="line number12 index11 alt1">
012
</div>
<div class="line number13 index12 alt2">
013
</div>
<div class="line number14 index13 alt1">
014
</div>
<div class="line number15 index14 alt2">
015
</div>
<div class="line number16 index15 alt1">
016
</div>
<div class="line number17 index16 alt2">
017
</div>
<div class="line number18 index17 alt1">
018
</div>
<div class="line number19 index18 alt2">
019
</div>
<div class="line number20 index19 alt1">
020
</div>
<div class="line number21 index20 alt2">
021
</div>
<div class="line number22 index21 alt1">
022
</div>
<div class="line number23 index22 alt2">
023
</div>
<div class="line number24 index23 alt1">
024
</div>
<div class="line number25 index24 alt2">
025
</div>
<div class="line number26 index25 alt1">
026
</div>
<div class="line number27 index26 alt2">
027
</div>
<div class="line number28 index27 alt1">
028
</div>
<div class="line number29 index28 alt2">
029
</div>
<div class="line number30 index29 alt1">
030
</div>
<div class="line number31 index30 alt2">
031
</div>
<div class="line number32 index31 alt1">
032
</div>
<div class="line number33 index32 alt2">
033
</div>
<div class="line number34 index33 alt1">
034
</div>
<div class="line number35 index34 alt2">
035
</div>
<div class="line number36 index35 alt1">
036
</div>
<div class="line number37 index36 alt2">
037
</div>
<div class="line number38 index37 alt1">
038
</div>
<div class="line number39 index38 alt2">
039
</div>
<div class="line number40 index39 alt1">
040
</div>
<div class="line number41 index40 alt2">
041
</div>
<div class="line number42 index41 alt1">
042
</div>
<div class="line number43 index42 alt2">
043
</div>
<div class="line number44 index43 alt1">
044
</div>
<div class="line number45 index44 alt2">
045
</div>
<div class="line number46 index45 alt1">
046
</div>
<div class="line number47 index46 alt2">
047
</div>
<div class="line number48 index47 alt1">
048
</div>
<div class="line number49 index48 alt2">
049
</div>
<div class="line number50 index49 alt1">
050
</div>
<div class="line number51 index50 alt2">
051
</div>
<div class="line number52 index51 alt1">
052
</div>
<div class="line number53 index52 alt2">
053
</div>
<div class="line number54 index53 alt1">
054
</div>
<div class="line number55 index54 alt2">
055
</div>
<div class="line number56 index55 alt1">
056
</div>
<div class="line number57 index56 alt2">
057
</div>
<div class="line number58 index57 alt1">
058
</div>
<div class="line number59 index58 alt2">
059
</div>
<div class="line number60 index59 alt1">
060
</div>
<div class="line number61 index60 alt2">
061
</div>
<div class="line number62 index61 alt1">
062
</div>
<div class="line number63 index62 alt2">
063
</div>
<div class="line number64 index63 alt1">
064
</div>
<div class="line number65 index64 alt2">
065
</div>
<div class="line number66 index65 alt1">
066
</div>
<div class="line number67 index66 alt2">
067
</div>
<div class="line number68 index67 alt1">
068
</div>
<div class="line number69 index68 alt2">
069
</div>
<div class="line number70 index69 alt1">
070
</div>
<div class="line number71 index70 alt2">
071
</div>
<div class="line number72 index71 alt1">
072
</div>
<div class="line number73 index72 alt2">
073
</div>
<div class="line number74 index73 alt1">
074
</div>
<div class="line number75 index74 alt2">
075
</div>
<div class="line number76 index75 alt1">
076
</div>
<div class="line number77 index76 alt2">
077
</div>
<div class="line number78 index77 alt1">
078
</div>
<div class="line number79 index78 alt2">
079
</div>
<div class="line number80 index79 alt1">
080
</div>
<div class="line number81 index80 alt2">
081
</div>
<div class="line number82 index81 alt1">
082
</div>
<div class="line number83 index82 alt2">
083
</div>
<div class="line number84 index83 alt1">
084
</div>
<div class="line number85 index84 alt2">
085
</div>
<div class="line number86 index85 alt1">
086
</div>
<div class="line number87 index86 alt2">
087
</div>
<div class="line number88 index87 alt1">
088
</div>
<div class="line number89 index88 alt2">
089
</div>
<div class="line number90 index89 alt1">
090
</div>
<div class="line number91 index90 alt2">
091
</div>
<div class="line number92 index91 alt1">
092
</div>
<div class="line number93 index92 alt2">
093
</div>
<div class="line number94 index93 alt1">
094
</div>
<div class="line number95 index94 alt2">
095
</div>
<div class="line number96 index95 alt1">
096
</div>
<div class="line number97 index96 alt2">
097
</div>
<div class="line number98 index97 alt1">
098
</div>
<div class="line number99 index98 alt2">
099
</div>
<div class="line number100 index99 alt1">
100
</div>
<div class="line number101 index100 alt2">
101
</div>
<div class="line number102 index101 alt1">
102
</div>
<div class="line number103 index102 alt2">
103
</div>
<div class="line number104 index103 alt1">
104
</div>
<div class="line number105 index104 alt2">
105
</div>
<div class="line number106 index105 alt1">
106
</div>
<div class="line number107 index106 alt2">
107
</div>
<div class="line number108 index107 alt1">
108
</div>
<div class="line number109 index108 alt2">
109
</div>
<div class="line number110 index109 alt1">
110
</div>
<div class="line number111 index110 alt2">
111
</div>
<div class="line number112 index111 alt1">
112
</div>
<div class="line number113 index112 alt2">
113
</div>
<div class="line number114 index113 alt1">
114
</div>
<div class="line number115 index114 alt2">
115
</div>
<div class="line number116 index115 alt1">
116
</div>
<div class="line number117 index116 alt2">
117
</div>
<div class="line number118 index117 alt1">
118
</div>
<div class="line number119 index118 alt2">
119
</div>
<div class="line number120 index119 alt1">
120
</div>
<div class="line number121 index120 alt2">
121
</div>
<div class="line number122 index121 alt1">
122
</div>
<div class="line number123 index122 alt2">
123
</div>
<div class="line number124 index123 alt1">
124
</div>
<div class="line number125 index124 alt2">
125
</div>
<div class="line number126 index125 alt1">
126
</div>
<div class="line number127 index126 alt2">
127
</div>
<div class="line number128 index127 alt1">
128
</div>
<div class="line number129 index128 alt2">
129
</div>
<div class="line number130 index129 alt1">
130
</div>
<div class="line number131 index130 alt2">
131
</div>
<div class="line number132 index131 alt1">
132
</div>
<div class="line number133 index132 alt2">
133
</div>
<div class="line number134 index133 alt1">
134
</div>
<div class="line number135 index134 alt2">
135
</div>
<div class="line number136 index135 alt1">
136
</div>
<div class="line number137 index136 alt2">
137
</div>
<div class="line number138 index137 alt1">
138
</div>
<div class="line number139 index138 alt2">
139
</div>
<div class="line number140 index139 alt1">
140
</div>
<div class="line number141 index140 alt2">
141
</div>
<div class="line number142 index141 alt1">
142
</div>
<div class="line number143 index142 alt2">
143
</div>
<div class="line number144 index143 alt1">
144
</div>
<div class="line number145 index144 alt2">
145
</div>
<div class="line number146 index145 alt1">
146
</div>
<div class="line number147 index146 alt2">
147
</div>
<div class="line number148 index147 alt1">
148
</div>
<div class="line number149 index148 alt2">
149
</div>
<div class="line number150 index149 alt1">
150
</div>
<div class="line number151 index150 alt2">
151
</div>
<div class="line number152 index151 alt1">
152
</div>
<div class="line number153 index152 alt2">
153
</div>
<div class="line number154 index153 alt1">
154
</div>
<div class="line number155 index154 alt2">
155
</div>
<div class="line number156 index155 alt1">
156
</div>
<div class="line number157 index156 alt2">
157
</div>
<div class="line number158 index157 alt1">
158
</div>
<div class="line number159 index158 alt2">
159
</div>
<div class="line number160 index159 alt1">
160
</div>
<div class="line number161 index160 alt2">
161
</div>
<div class="line number162 index161 alt1">
162
</div>
<div class="line number163 index162 alt2">
163
</div>
<div class="line number164 index163 alt1">
164
</div>
<div class="line number165 index164 alt2">
165
</div>
<div class="line number166 index165 alt1">
166
</div>
<div class="line number167 index166 alt2">
167
</div>
</td>
<td class="code">
<div class="container">
<div class="line number1 index0 alt2">
`<font color=``"#362e2b"``><font style=``"background-color:rgb(255, 255, 255)"``><font face=``"Arial"``><font style=``"font-size:14px"``>``package` `com.czm.flowlayout;`
</div>
<div class="line number2 index1 alt1">
</div>
<div class="line number3 index2 alt2">
`import` `java.util.ArrayList;`
</div>
<div class="line number4 index3 alt1">
`import` `java.util.List;`
</div>
<div class="line number5 index4 alt2">
</div>
<div class="line number6 index5 alt1">
`import` `android.content.Context;`
</div>
<div class="line number7 index6 alt2">
`import` `android.util.AttributeSet;`
</div>
<div class="line number8 index7 alt1">
`import` `android.view.View;`
</div>
<div class="line number9 index8 alt2">
`import` `android.view.ViewGroup;`
</div>
<div class="line number10 index9 alt1">
`/**`
</div>
<div class="line number11 index10 alt2">
` ``* `
</div>
<div class="line number12 index11 alt1">
` ``* @author caizhiming`
</div>
<div class="line number13 index12 alt2">
` ``* @created on 2015-4-13`
</div>
<div class="line number14 index13 alt1">
` ``*/`
</div>
<div class="line number15 index14 alt2">
`public` `class` `XCFlowLayout ``extends` `ViewGroup{`
</div>
<div class="line number16 index15 alt1">
</div>
<div class="line number17 index16 alt2">
` ``//存储所有子View`
</div>
<div class="line number18 index17 alt1">
` ``private` `List<List<View>> mAllChildViews = ``new` `ArrayList<>();`
</div>
<div class="line number19 index18 alt2">
` ``//每一行的高度`
</div>
<div class="line number20 index19 alt1">
` ``private` `List<Integer> mLineHeight = ``new` `ArrayList<>();`
</div>
<div class="line number21 index20 alt2">
` `
</div>
<div class="line number22 index21 alt1">
` ``public` `XCFlowLayout(Context context) {`
</div>
<div class="line number23 index22 alt2">
` ``this``(context, ``null``);`
</div>
<div class="line number24 index23 alt1">
` ``// TODO Auto-generated constructor stub`
</div>
<div class="line number25 index24 alt2">
` ``}`
</div>
<div class="line number26 index25 alt1">
` ``public` `XCFlowLayout(Context context, AttributeSet attrs) {`
</div>
<div class="line number27 index26 alt2">
` ``this``(context, attrs, ````);`
</div>
<div class="line number28 index27 alt1">
` ``// TODO Auto-generated constructor stub`
</div>
<div class="line number29 index28 alt2">
` ``}`
</div>
<div class="line number30 index29 alt1">
` ``public` `XCFlowLayout(Context context, AttributeSet attrs, ``int` `defStyle) {`
</div>
<div class="line number31 index30 alt2">
` ``super``(context, attrs, defStyle);`
</div>
<div class="line number32 index31 alt1">
` ``// TODO Auto-generated constructor stub`
</div>
<div class="line number33 index32 alt2">
` ``}`
</div>
<div class="line number34 index33 alt1">
` ``@Override`
</div>
<div class="line number35 index34 alt2">
` ``protected` `void` `onMeasure(``int` `widthMeasureSpec, ``int` `heightMeasureSpec) {`
</div>
<div class="line number36 index35 alt1">
` ``// TODO Auto-generated method stub`
</div>
<div class="line number37 index36 alt2">
` `
</div>
<div class="line number38 index37 alt1">
` ``//父控件传进来的宽度和高度以及对应的测量模式`
</div>
<div class="line number39 index38 alt2">
` ``int` `sizeWidth = MeasureSpec.getSize(widthMeasureSpec);`
</div>
<div class="line number40 index39 alt1">
` ``int` `modeWidth = MeasureSpec.getMode(widthMeasureSpec);`
</div>
<div class="line number41 index40 alt2">
` ``int` `sizeHeight = MeasureSpec.getSize(heightMeasureSpec);`
</div>
<div class="line number42 index41 alt1">
` ``int` `modeHeight = MeasureSpec.getMode(heightMeasureSpec);`
</div>
<div class="line number43 index42 alt2">
` `
</div>
<div class="line number44 index43 alt1">
` ``//如果当前ViewGroup的宽高为wrap_content的情况`
</div>
<div class="line number45 index44 alt2">
` ``int` `width = ````;``//自己测量的 宽度`
</div>
<div class="line number46 index45 alt1">
` ``int` `height = ````;``//自己测量的高度`
</div>
<div class="line number47 index46 alt2">
` ``//记录每一行的宽度和高度`
</div>
<div class="line number48 index47 alt1">
` ``int` `lineWidth = ````;`
</div>
<div class="line number49 index48 alt2">
` ``int` `lineHeight = ````;`
</div>
<div class="line number50 index49 alt1">
` `
</div>
<div class="line number51 index50 alt2">
` ``//获取子view的个数`
</div>
<div class="line number52 index51 alt1">
` ``int` `childCount = getChildCount();`
</div>
<div class="line number53 index52 alt2">
` ``for``(``int` `i = ````;i < childCount; i ++){`
</div>
<div class="line number54 index53 alt1">
` ``View child = getChildAt(i);`
</div>
<div class="line number55 index54 alt2">
` ``//测量子View的宽和高`
</div>
<div class="line number56 index55 alt1">
` ``measureChild(child, widthMeasureSpec, heightMeasureSpec);`
</div>
<div class="line number57 index56 alt2">
` ``//得到LayoutParams`
</div>
<div class="line number58 index57 alt1">
` ``MarginLayoutParams lp = (MarginLayoutParams) getLayoutParams();`
</div>
<div class="line number59 index58 alt2">
` ``//子View占据的宽度`
</div>
<div class="line number60 index59 alt1">
` ``int` `childWidth = child.getMeasuredWidth() + lp.leftMargin + lp.rightMargin;`
</div>
<div class="line number61 index60 alt2">
` ``//子View占据的高度`
</div>
<div class="line number62 index61 alt1">
` ``int` `childHeight = child.getMeasuredHeight() + lp.topMargin + lp.bottomMargin;`
</div>
<div class="line number63 index62 alt2">
` ``//换行时候`
</div>
<div class="line number64 index63 alt1">
` ``if``(lineWidth + childWidth > sizeWidth){`
</div>
<div class="line number65 index64 alt2">
` ``//对比得到最大的宽度`
</div>
<div class="line number66 index65 alt1">
` ``width = Math.max(width, lineWidth);`
</div>
<div class="line number67 index66 alt2">
` ``//重置lineWidth`
</div>
<div class="line number68 index67 alt1">
` ``lineWidth = childWidth;`
</div>
<div class="line number69 index68 alt2">
` ``//记录行高`
</div>
<div class="line number70 index69 alt1">
` ``height += lineHeight;`
</div>
<div class="line number71 index70 alt2">
` ``lineHeight = childHeight;`
</div>
<div class="line number72 index71 alt1">
` ``}``else``{``//不换行情况`
</div>
<div class="line number73 index72 alt2">
` ``//叠加行宽`
</div>
<div class="line number74 index73 alt1">
` ``lineWidth += childWidth;`
</div>
<div class="line number75 index74 alt2">
` ``//得到最大行高`
</div>
<div class="line number76 index75 alt1">
` ``lineHeight = Math.max(lineHeight, childHeight);`
</div>
<div class="line number77 index76 alt2">
` ``}`
</div>
<div class="line number78 index77 alt1">
` ``//处理最后一个子View的情况`
</div>
<div class="line number79 index78 alt2">
` ``if``(i == childCount -``1``){`
</div>
<div class="line number80 index79 alt1">
` ``width = Math.max(width, lineWidth);`
</div>
<div class="line number81 index80 alt2">
` ``height += lineHeight;`
</div>
<div class="line number82 index81 alt1">
` ``}`
</div>
<div class="line number83 index82 alt2">
` ``}`
</div>
<div class="line number84 index83 alt1">
` ``//wrap_content`
</div>
<div class="line number85 index84 alt2">
` ``setMeasuredDimension(modeWidth == MeasureSpec.EXACTLY ? sizeWidth : width,`
</div>
<div class="line number86 index85 alt1">
` ``modeHeight == MeasureSpec.EXACTLY ? sizeHeight : height);`
</div>
<div class="line number87 index86 alt2">
` ``super``.onMeasure(widthMeasureSpec, heightMeasureSpec);`
</div>
<div class="line number88 index87 alt1">
` ``}`
</div>
<div class="line number89 index88 alt2">
` `
</div>
<div class="line number90 index89 alt1">
` ``@Override`
</div>
<div class="line number91 index90 alt2">
` ``protected` `void` `onLayout(``boolean` `changed, ``int` `l, ``int` `t, ``int` `r, ``int` `b) {`
</div>
<div class="line number92 index91 alt1">
` ``// TODO Auto-generated method stub`
</div>
<div class="line number93 index92 alt2">
` ``mAllChildViews.clear();`
</div>
<div class="line number94 index93 alt1">
` ``mLineHeight.clear();`
</div>
<div class="line number95 index94 alt2">
` ``//获取当前ViewGroup的宽度`
</div>
<div class="line number96 index95 alt1">
` ``int` `width = getWidth();`
</div>
<div class="line number97 index96 alt2">
` `
</div>
<div class="line number98 index97 alt1">
` ``int` `lineWidth = ````;`
</div>
<div class="line number99 index98 alt2">
` ``int` `lineHeight = ````;`
</div>
<div class="line number100 index99 alt1">
` ``//记录当前行的view`
</div>
<div class="line number101 index100 alt2">
` ``List<View> lineViews = ``new` `ArrayList<View>();`
</div>
<div class="line number102 index101 alt1">
` ``int` `childCount = getChildCount();`
</div>
<div class="line number103 index102 alt2">
` ``for``(``int` `i = ````;i < childCount; i ++){`
</div>
<div class="line number104 index103 alt1">
` ``View child = getChildAt(i);`
</div>
<div class="line number105 index104 alt2">
` ``MarginLayoutParams lp = (MarginLayoutParams) child.getLayoutParams();`
</div>
<div class="line number106 index105 alt1">
` ``int` `childWidth = child.getMeasuredWidth();`
</div>
<div class="line number107 index106 alt2">
` ``int` `childHeight = child.getMeasuredHeight();`
</div>
<div class="line number108 index107 alt1">
` `
</div>
<div class="line number109 index108 alt2">
` ``//如果需要换行`
</div>
<div class="line number110 index109 alt1">
` ``if``(childWidth + lineWidth + lp.leftMargin + lp.rightMargin > width){`
</div>
<div class="line number111 index110 alt2">
` ``//记录LineHeight`
</div>
<div class="line number112 index111 alt1">
` ``mLineHeight.add(lineHeight);`
</div>
<div class="line number113 index112 alt2">
` ``//记录当前行的Views`
</div>
<div class="line number114 index113 alt1">
` ``mAllChildViews.add(lineViews);`
</div>
<div class="line number115 index114 alt2">
` ``//重置行的宽高`
</div>
<div class="line number116 index115 alt1">
` ``lineWidth = ````;`
</div>
<div class="line number117 index116 alt2">
` ``lineHeight = childHeight + lp.topMargin + lp.bottomMargin;`
</div>
<div class="line number118 index117 alt1">
` ``//重置view的集合`
</div>
<div class="line number119 index118 alt2">
` ``lineViews = ``new` `ArrayList();`
</div>
<div class="line number120 index119 alt1">
` ``}`
</div>
<div class="line number121 index120 alt2">
` ``lineWidth += childWidth + lp.leftMargin + lp.rightMargin;`
</div>
<div class="line number122 index121 alt1">
` ``lineHeight = Math.max(lineHeight, childHeight + lp.topMargin + lp.bottomMargin);`
</div>
<div class="line number123 index122 alt2">
` ``lineViews.add(child);`
</div>
<div class="line number124 index123 alt1">
` ``}`
</div>
<div class="line number125 index124 alt2">
` ``//处理最后一行`
</div>
<div class="line number126 index125 alt1">
` ``mLineHeight.add(lineHeight);`
</div>
<div class="line number127 index126 alt2">
` ``mAllChildViews.add(lineViews);`
</div>
<div class="line number128 index127 alt1">
` `
</div>
<div class="line number129 index128 alt2">
` ``//设置子View的位置`
</div>
<div class="line number130 index129 alt1">
` ``int` `left = ````;`
</div>
<div class="line number131 index130 alt2">
` ``int` `top = ````;`
</div>
<div class="line number132 index131 alt1">
` ``//获取行数`
</div>
<div class="line number133 index132 alt2">
` ``int` `lineCount = mAllChildViews.size();`
</div>
<div class="line number134 index133 alt1">
` ``for``(``int` `i = ````; i < lineCount; i ++){`
</div>
<div class="line number135 index134 alt2">
` ``//当前行的views和高度`
</div>
<div class="line number136 index135 alt1">
` ``lineViews = mAllChildViews.get(i);`
</div>
<div class="line number137 index136 alt2">
` ``lineHeight = mLineHeight.get(i);`
</div>
<div class="line number138 index137 alt1">
` ``for``(``int` `j = ````; j < lineViews.size(); j ++){`
</div>
<div class="line number139 index138 alt2">
` ``View child = lineViews.get(j);`
</div>
<div class="line number140 index139 alt1">
` ``//判断是否显示`
</div>
<div class="line number141 index140 alt2">
` ``if``(child.getVisibility() == View.GONE){`
</div>
<div class="line number142 index141 alt1">
` ``continue``;`
</div>
<div class="line number143 index142 alt2">
` ``}`
</div>
<div class="line number144 index143 alt1">
` ``MarginLayoutParams lp = (MarginLayoutParams) child.getLayoutParams();`
</div>
<div class="line number145 index144 alt2">
` ``int` `cLeft = left + lp.leftMargin;`
</div>
<div class="line number146 index145 alt1">
` ``int` `cTop = top + lp.topMargin;`
</div>
<div class="line number147 index146 alt2">
` ``int` `cRight = cLeft + child.getMeasuredWidth();`
</div>
<div class="line number148 index147 alt1">
` ``int` `cBottom = cTop + child.getMeasuredHeight();`
</div>
<div class="line number149 index148 alt2">
` ``//进行子View进行布局`
</div>
<div class="line number150 index149 alt1">
` ``child.layout(cLeft, cTop, cRight, cBottom);`
</div>
<div class="line number151 index150 alt2">
` ``left += child.getMeasuredWidth() + lp.leftMargin + lp.rightMargin;`
</div>
<div class="line number152 index151 alt1">
` ``}`
</div>
<div class="line number153 index152 alt2">
` ``left = ````;`
</div>
<div class="line number154 index153 alt1">
` ``top += lineHeight;`
</div>
<div class="line number155 index154 alt2">
` ``}`
</div>
<div class="line number156 index155 alt1">
` `
</div>
<div class="line number157 index156 alt2">
` ``}`
</div>
<div class="line number158 index157 alt1">
` ``/**`
</div>
<div class="line number159 index158 alt2">
` ``* 与当前ViewGroup对应的LayoutParams`
</div>
<div class="line number160 index159 alt1">
` ``*/`
</div>
<div class="line number161 index160 alt2">
` ``@Override`
</div>
<div class="line number162 index161 alt1">
` ``public` `LayoutParams generateLayoutParams(AttributeSet attrs) {`
</div>
<div class="line number163 index162 alt2">
` ``// TODO Auto-generated method stub`
</div>
<div class="line number164 index163 alt1">
` `
</div>
<div class="line number165 index164 alt2">
` ``return` `new` `MarginLayoutParams(getContext(), attrs);`
</div>
<div class="line number166 index165 alt1">
` ``}`
</div>
<div class="line number167 index166 alt2">
`}</font></font></font></font>`
</div>
</div>
</td>
</tr>
</table>
</div>
2.相关的布局文件:
引用自定义控件:
<table border="0" cellspacing="0" cellpadding="0">
<tr>
<td class="gutter">
<div class="line number1 index0 alt2">
01
</div>
<div class="line number2 index1 alt1">
02
</div>
<div class="line number3 index2 alt2">
03
</div>
<div class="line number4 index3 alt1">
04
</div>
<div class="line number5 index4 alt2">
05
</div>
<div class="line number6 index5 alt1">
06
</div>
<div class="line number7 index6 alt2">
07
</div>
<div class="line number8 index7 alt1">
08
</div>
<div class="line number9 index8 alt2">
09
</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>
</td>
<td class="code">
<div class="container">
<div class="line number1 index0 alt2">
`<font color=``"#362e2b"``><font style=``"background-color:rgb(255, 255, 255)"``><font face=``"Arial"``><font style=``"font-size:14px"``><RelativeLayout xmlns:android=``"<a href="http://schemas.android.com/apk/res/android">http://schemas.android.com/apk/res/android</a>"`
</div>
<div class="line number2 index1 alt1">
` ``xmlns:tools=``"<a href="http://schemas.android.com/tools">http://schemas.android.com/tools</a>"`
</div>
<div class="line number3 index2 alt2">
` ``android:id=``"@+id/container"`
</div>
<div class="line number4 index3 alt1">
` ``android:layout_width=``"match_parent"`
</div>
<div class="line number5 index4 alt2">
` ``android:layout_height=``"match_parent"` `>`
</div>
<div class="line number6 index5 alt1">
</div>
<div class="line number7 index6 alt2">
` ``<com.czm.flowlayout.XCFlowLayout`
</div>
<div class="line number8 index7 alt1">
` ``android:id=``"@+id/flowlayout"`
</div>
<div class="line number9 index8 alt2">
` ``android:layout_width=``"match_parent"`
</div>
<div class="line number10 index9 alt1">
` ``android:layout_height=``"match_parent"` `>`
</div>
<div class="line number11 index10 alt2">
</div>
<div class="line number12 index11 alt1">
` ``</com.czm.flowlayout.XCFlowLayout>`
</div>
<div class="line number13 index12 alt2">
</div>
<div class="line number14 index13 alt1">
`</RelativeLayout></font></font></font></font>`
</div>
</div>
</td>
</tr>
</table>
</div>
TextView的样式文件:
<table border="0" cellspacing="0" cellpadding="0">
<tr>
<td class="gutter">
<div class="line number1 index0 alt2">
01
</div>
<div class="line number2 index1 alt1">
02
</div>
<div class="line number3 index2 alt2">
03
</div>
<div class="line number4 index3 alt1">
04
</div>
<div class="line number5 index4 alt2">
05
</div>
<div class="line number6 index5 alt1">
06
</div>
<div class="line number7 index6 alt2">
07
</div>
<div class="line number8 index7 alt1">
08
</div>
<div class="line number9 index8 alt2">
09
</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>
</td>
<td class="code">
<div class="container">
<div class="line number1 index0 alt2">
`<font color=``"#362e2b"``><font style=``"background-color:rgb(255, 255, 255)"``><font face=``"Arial"``><font style=``"font-size:14px"``><?xml version=``"1.0"` `encoding=``"utf-8"``?>`
</div>
<div class="line number2 index1 alt1">
`<shape xmlns:android=``"<a href="http://schemas.android.com/apk/res/android">http://schemas.android.com/apk/res/android</a>"` `>`
</div>
<div class="line number3 index2 alt2">
` ``<solid android:color=``"#666666"` `/>`
</div>
<div class="line number4 index3 alt1">
` ``<corners android:radius=``"10dp"` `/>`
</div>
<div class="line number5 index4 alt2">
` ``<padding `
</div>
<div class="line number6 index5 alt1">
` ``android:left=``"5dp"`
</div>
<div class="line number7 index6 alt2">
` ``android:right=``"5dp"`
</div>
<div class="line number8 index7 alt1">
` ``android:top=``"5dp"`
</div>
<div class="line number9 index8 alt2">
` ``android:bottom=``"5dp"`
</div>
<div class="line number10 index9 alt1">
` ``/>`
</div>
<div class="line number11 index10 alt2">
</div>
<div class="line number12 index11 alt1">
`</shape></font></font></font></font>`
</div>
</div>
</td>
</tr>
</table>
</div>
三、使用该自定义布局控件类
最后,如何使用该自定义的热门标签控件类呢?很简单,请看下面实例代码:
<table border="0" cellspacing="0" cellpadding="0">
<tr>
<td class="gutter">
<div class="line number1 index0 alt2">
01
</div>
<div class="line number2 index1 alt1">
02
</div>
<div class="line number3 index2 alt2">
03
</div>
<div class="line number4 index3 alt1">
04
</div>
<div class="line number5 index4 alt2">
05
</div>
<div class="line number6 index5 alt1">
06
</div>
<div class="line number7 index6 alt2">
07
</div>
<div class="line number8 index7 alt1">
08
</div>
<div class="line number9 index8 alt2">
09
</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>
</td>
<td class="code">
<div class="container">
<div class="line number1 index0 alt2">
`<font color=``"#362e2b"``><font style=``"background-color:rgb(255, 255, 255)"``><font face=``"Arial"``><font style=``"font-size:14px"``>``package` `com.czm.flowlayout;`
</div>
<div class="line number2 index1 alt1">
</div>
<div class="line number3 index2 alt2">
`import` `android.app.Activity;`
</div>
<div class="line number4 index3 alt1">
`import` `android.graphics.Color;`
</div>
<div class="line number5 index4 alt2">
`import` `android.os.Bundle;`
</div>
<div class="line number6 index5 alt1">
`import` `android.view.ViewGroup.LayoutParams;`
</div>
<div class="line number7 index6 alt2">
`import` `android.view.ViewGroup.MarginLayoutParams;`
</div>
<div class="line number8 index7 alt1">
`import` `android.widget.TextView;`
</div>
<div class="line number9 index8 alt2">
`/**`
</div>
<div class="line number10 index9 alt1">
` ``* `
</div>
<div class="line number11 index10 alt2">
` ``* @author caizhiming`
</div>
<div class="line number12 index11 alt1">
` ``* @created on 2015-4-13`
</div>
<div class="line number13 index12 alt2">
` ``*/`
</div>
<div class="line number14 index13 alt1">
`public` `class` `MainActivity ``extends` `Activity {`
</div>
<div class="line number15 index14 alt2">
</div>
<div class="line number16 index15 alt1">
` ``private` `String mNames[] = {`
</div>
<div class="line number17 index16 alt2">
` ``"welcome"``,``"android"``,``"TextView"``,`
</div>
<div class="line number18 index17 alt1">
` ``"apple"``,``"jamy"``,``"kobe bryant"``,`
</div>
<div class="line number19 index18 alt2">
` ``"jordan"``,``"layout"``,``"viewgroup"``,`
</div>
<div class="line number20 index19 alt1">
` ``"margin"``,``"padding"``,``"text"``,`
</div>
<div class="line number21 index20 alt2">
` ``"name"``,``"type"``,``"search"``,``"logcat"`
</div>
<div class="line number22 index21 alt1">
` ``};`
</div>
<div class="line number23 index22 alt2">
` ``private` `XCFlowLayout mFlowLayout;`
</div>
<div class="line number24 index23 alt1">
` ``@Override`
</div>
<div class="line number25 index24 alt2">
` ``protected` `void` `onCreate(Bundle savedInstanceState) {`
</div>
<div class="line number26 index25 alt1">
` ``super``.onCreate(savedInstanceState);`
</div>
<div class="line number27 index26 alt2">
` ``setContentView(R.layout.activity_main);`
</div>
<div class="line number28 index27 alt1">
` `
</div>
<div class="line number29 index28 alt2">
` ``initChildViews();`
</div>
<div class="line number30 index29 alt1">
` `
</div>
<div class="line number31 index30 alt2">
` ``}`
</div>
<div class="line number32 index31 alt1">
` ``private` `void` `initChildViews() {`
</div>
<div class="line number33 index32 alt2">
` ``// TODO Auto-generated method stub`
</div>
<div class="line number34 index33 alt1">
` ``mFlowLayout = (XCFlowLayout) findViewById(R.id.flowlayout);`
</div>
<div class="line number35 index34 alt2">
` ``MarginLayoutParams lp = ``new` `MarginLayoutParams(`
</div>
<div class="line number36 index35 alt1">
` ``LayoutParams.WRAP_CONTENT,LayoutParams.WRAP_CONTENT);`
</div>
<div class="line number37 index36 alt2">
` ``lp.leftMargin = ``5``;`
</div>
<div class="line number38 index37 alt1">
` ``lp.rightMargin = ``5``;`
</div>
<div class="line number39 index38 alt2">
` ``lp.topMargin = ``5``;`
</div>
<div class="line number40 index39 alt1">
` ``lp.bottomMargin = ``5``;`
</div>
<div class="line number41 index40 alt2">
` ``for``(``int` `i = ````; i < mNames.length; i ++){`
</div>
<div class="line number42 index41 alt1">
` ``TextView view = ``new` `TextView(``this``);`
</div>
<div class="line number43 index42 alt2">
` ``view.setText(mNames[i]);`
</div>
<div class="line number44 index43 alt1">
` ``view.setTextColor(Color.WHITE);`
</div>
<div class="line number45 index44 alt2">
` ``view.setBackgroundDrawable(getResources().getDrawable(R.drawable.textview_bg));`
</div>
<div class="line number46 index45 alt1">
` ``mFlowLayout.addView(view,lp);`
</div>
<div class="line number47 index46 alt2">
` ``}`
</div>
<div class="line number48 index47 alt1">
` ``}`
</div>
<div class="line number49 index48 alt2">
</div>
<div class="line number50 index49 alt1">
`}</font></font></font></font>`
</div>
</div>
</td>
</tr>
</table>
</div>
转自:http://www.apkbus.com/android-239725-1-1.html
💬 评论