android流式布局实现
java:
import
java.util.ArrayList;
import
java.util.List;
import
android.content.Context;
import
android.util.AttributeSet;
import
android.view.View;
import
android.view.ViewGroup;
/**
*
* @author caizhiming
* @created on 2015-4-13
*/
public
class
XCFlowLayout
extends
ViewGroup{
//存储所有子View
private
List<List<View>> mAllChildViews =
new
ArrayList<>();
//每一行的高度
private
List<Integer> mLineHeight =
new
ArrayList<>();
public
XCFlowLayout(Context context) {
this
(context,
null
);
// TODO Auto-generated constructor stub
}
public
XCFlowLayout(Context context, AttributeSet attrs) {
this
(context, attrs,
0
);
// TODO Auto-generated constructor stub
}
public
XCFlowLayout(Context context, AttributeSet attrs,
int
defStyle) {
super
(context, attrs, defStyle);
// TODO Auto-generated constructor stub
}
@Override
protected
void
onMeasure(
int
widthMeasureSpec,
int
heightMeasureSpec) {
// TODO Auto-generated method stub
//父控件传进来的宽度和高度以及对应的测量模式
int
sizeWidth = MeasureSpec.getSize(widthMeasureSpec);
int
modeWidth = MeasureSpec.getMode(widthMeasureSpec);
int
sizeHeight = MeasureSpec.getSize(heightMeasureSpec);
int
modeHeight = MeasureSpec.getMode(heightMeasureSpec);
//如果当前ViewGroup的宽高为wrap_content的情况
int
width =
0
;
//自己测量的 宽度
int
height =
0
;
//自己测量的高度
//记录每一行的宽度和高度
int
lineWidth =
0
;
int
lineHeight =
0
;
//获取子view的个数
int
childCount = getChildCount();
for
(
int
i =
0
;i < childCount; i ++){
View child = getChildAt(i);
//测量子View的宽和高
measureChild(child, widthMeasureSpec, heightMeasureSpec);
//得到LayoutParams
MarginLayoutParams lp = (MarginLayoutParams) getLayoutParams();
//子View占据的宽度
int
childWidth = child.getMeasuredWidth() + lp.leftMargin + lp.rightMargin;
//子View占据的高度
int
childHeight = child.getMeasuredHeight() + lp.topMargin + lp.bottomMargin;
//换行时候
if
(lineWidth + childWidth > sizeWidth){
//对比得到最大的宽度
width = Math.max(width, lineWidth);
//重置lineWidth
lineWidth = childWidth;
//记录行高
height += lineHeight;
lineHeight = childHeight;
}
else
{
//不换行情况
//叠加行宽
lineWidth += childWidth;
//得到最大行高
lineHeight = Math.max(lineHeight, childHeight);
}
//处理最后一个子View的情况
if
(i == childCount -
1
){
width = Math.max(width, lineWidth);
height += lineHeight;
}
}
//wrap_content
setMeasuredDimension(modeWidth == MeasureSpec.EXACTLY ? sizeWidth : width,
modeHeight == MeasureSpec.EXACTLY ? sizeHeight : height);
super
.onMeasure(widthMeasureSpec, heightMeasureSpec);
}
@Override
protected
void
onLayout(
boolean
changed,
int
l,
int
t,
int
r,
int
b) {
// TODO Auto-generated method stub
mAllChildViews.clear();
mLineHeight.clear();
//获取当前ViewGroup的宽度
int
width = getWidth();
int
lineWidth =
0
;
int
lineHeight =
0
;
//记录当前行的view
List<View> lineViews =
new
ArrayList<View>();
int
childCount = getChildCount();
for
(
int
i =
0
;i < childCount; i ++){
View child = getChildAt(i);
MarginLayoutParams lp = (MarginLayoutParams) child.getLayoutParams();
int
childWidth = child.getMeasuredWidth();
int
childHeight = child.getMeasuredHeight();
//如果需要换行
if
(childWidth + lineWidth + lp.leftMargin + lp.rightMargin > width){
//记录LineHeight
mLineHeight.add(lineHeight);
//记录当前行的Views
mAllChildViews.add(lineViews);
//重置行的宽高
lineWidth =
0
;
lineHeight = childHeight + lp.topMargin + lp.bottomMargin;
//重置view的集合
lineViews =
new
ArrayList();
}
lineWidth += childWidth + lp.leftMargin + lp.rightMargin;
lineHeight = Math.max(lineHeight, childHeight + lp.topMargin + lp.bottomMargin);
lineViews.add(child);
}
//处理最后一行
mLineHeight.add(lineHeight);
mAllChildViews.add(lineViews);
//设置子View的位置
int
left =
0
;
int
top =
0
;
//获取行数
int
lineCount = mAllChildViews.size();
for
(
int
i =
0
; i < lineCount; i ++){
//当前行的views和高度
lineViews = mAllChildViews.get(i);
lineHeight = mLineHeight.get(i);
for
(
int
j =
0
; j < lineViews.size(); j ++){
View child = lineViews.get(j);
//判断是否显示
if
(child.getVisibility() == View.GONE){
continue
;
}
MarginLayoutParams lp = (MarginLayoutParams) child.getLayoutParams();
int
cLeft = left + lp.leftMargin;
int
cTop = top + lp.topMargin;
int
cRight = cLeft + child.getMeasuredWidth();
int
cBottom = cTop + child.getMeasuredHeight();
//进行子View进行布局
child.layout(cLeft, cTop, cRight, cBottom);
left += child.getMeasuredWidth() + lp.leftMargin + lp.rightMargin;
}
left =
0
;
top += lineHeight;
}
}
/**
* 与当前ViewGroup对应的LayoutParams
*/
@Override
public
LayoutParams generateLayoutParams(AttributeSet attrs) {
// TODO Auto-generated method stub
return
new
MarginLayoutParams(getContext(), attrs);
}
}
———————————————–
布局:
<RelativeLayout xmlns:android=
"http://schemas.android.com/apk/res/android"
android:id=
"@+id/container"
android:layout_width=
"match_parent"
android:layout_height=
"match_parent"
>
<com.czm.flowlayout.XCFlowLayout
android:id=
"@+id/flowlayout"
android:layout_width=
"match_parent"
android:layout_height=
"match_parent"
>
</com.czm.flowlayout.XCFlowLayout>
</RelativeLayout>
———————————————
textview样式:
<?xml version=
"1.0"
encoding=
"utf-8"
?>
<solid android:color=
"#666666"
/>
<corners android:radius=
"10dp"
/>
<padding
android:left=
"5dp"
android:right=
"5dp"
android:top=
"5dp"
android:bottom=
"5dp"
/>
</shape>
————————————-
调用方法:
packagecom.czm.flowlayout;
importandroid.app.Activity;
importandroid.graphics.Color;
importandroid.os.Bundle;
importandroid.view.ViewGroup.LayoutParams;
importandroid.view.ViewGroup.MarginLayoutParams;
importandroid.widget.TextView;
/**
*
* @author caizhiming
* @created on 2015-4-13
*/
publicclassMainActivityextendsActivity {
privateString mNames[] = {
“welcome”,”android”,”TextView”,
“apple”,”jamy”,”kobe bryant”,
“jordan”,”layout”,”viewgroup”,
“margin”,”padding”,”text”,
“name”,”type”,”search”,”logcat”
};
privateXCFlowLayout mFlowLayout;
@Override
protectedvoidonCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initChildViews();
}
privatevoidinitChildViews() {
// TODO Auto-generated method stub
mFlowLayout = (XCFlowLayout) findViewById(R.id.flowlayout);
MarginLayoutParams lp =newMarginLayoutParams(
LayoutParams.WRAP_CONTENT,LayoutParams.WRAP_CONTENT);
lp.leftMargin =5;
lp.rightMargin =5;
lp.topMargin =5;
lp.bottomMargin =5;
for(inti =0; i < mNames.length; i ++){
TextView view =newTextView(this);
view.setText(mNames[i]);
view.setTextColor(Color.WHITE);
view.setBackgroundDrawable(getResources().getDrawable(R.drawable.textview_bg));
mFlowLayout.addView(view,lp);
}
}
}
importandroid.app.Activity;
importandroid.graphics.Color;
importandroid.os.Bundle;
importandroid.view.ViewGroup.LayoutParams;
importandroid.view.ViewGroup.MarginLayoutParams;
importandroid.widget.TextView;
/**
*
* @author caizhiming
* @created on 2015-4-13
*/
publicclassMainActivityextendsActivity {
privateString mNames[] = {
“welcome”,”android”,”TextView”,
“apple”,”jamy”,”kobe bryant”,
“jordan”,”layout”,”viewgroup”,
“margin”,”padding”,”text”,
“name”,”type”,”search”,”logcat”
};
privateXCFlowLayout mFlowLayout;
@Override
protectedvoidonCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initChildViews();
}
privatevoidinitChildViews() {
// TODO Auto-generated method stub
mFlowLayout = (XCFlowLayout) findViewById(R.id.flowlayout);
MarginLayoutParams lp =newMarginLayoutParams(
LayoutParams.WRAP_CONTENT,LayoutParams.WRAP_CONTENT);
lp.leftMargin =5;
lp.rightMargin =5;
lp.topMargin =5;
lp.bottomMargin =5;
for(inti =0; i < mNames.length; i ++){
TextView view =newTextView(this);
view.setText(mNames[i]);
view.setTextColor(Color.WHITE);
view.setBackgroundDrawable(getResources().getDrawable(R.drawable.textview_bg));
mFlowLayout.addView(view,lp);
}
}
}
文章来源:http://www.apkbus.com/android-239725-1-1.html
近期评论