简单实现流式布局,效果图如下
1,value下的attr文件
<?xml version="1.0" encoding="utf-8"?>
<resources>
<declare-styleable name="FlowView">
<attr name="pLeft" format="dimension"/>
<attr name="pRight" format="dimension"/>
<attr name="pTop" format="dimension"/>
<attr name="pBottom" format="dimension"/>
<attr name="hDiver" format="dimension"/>
<attr name="lDiver" format="dimension"/>
<attr name="itemLayout" format="reference"/>
<attr name="addLayout" format="reference"/>
</declare-styleable>
</resources>
2,要用到的三个布局文件
1)普通的item的选项的布局文件
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="wrap_content" android:layout_height="wrap_content" android:background="@drawable/background_item">
<TextView android:id="@+id/textView1" android:layout_width="wrap_content" android:layout_height="wrap_content" android:padding="5dip" android:textColor="#FFFFFF" android:text="TextView" />
</RelativeLayout>
2)add项的布局文件
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="wrap_content" android:layout_height="wrap_content" android:background="@drawable/background_add">
<TextView android:id="@+id/textView1" android:layout_width="wrap_content" android:layout_height="wrap_content" android:padding="5dip" android:textColor="#FFFFFF" android:text="TextView" />
</RelativeLayout>
3)main布局文件
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res/com.example.flowingdemo"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent">
<com.example.flowingdemo.view.FlowView
android:layout_width="match_parent"
android:layout_height="match_parent"
app:pLeft="20dip"
app:pRight="20dip"
app:pTop="20dip"
app:pBottom="20dip"
app:hDiver="20dip"
app:lDiver="20dip"
app:itemLayout="@layout/flow_item_layout"
app:addLayout="@layout/flow_add_layout"
android:id="@+id/flowview" />
</RelativeLayout>
3,自动的FlowView,继承ViewGroup,实现了OnClick接口
package com.example.flowingdemo.view;
import java.util.ArrayList;
import java.util.List;
import com.example.flowingdemo.R;
import android.content.Context;
import android.content.res.TypedArray;
import android.text.TextUtils;
import android.util.AttributeSet;
import android.util.TypedValue;
import android.view.View;
import android.view.ViewGroup;
import android.view.View.OnClickListener;
import android.widget.RelativeLayout;
import android.widget.TextView;
/* * 仅仅支持match_parent */
public class FlowView extends ViewGroup implements OnClickListener {
// item
private int itemLayout = 0;
// add
private int addLayout = 0;
// 布局的总的宽度和高度
private int totalWidth = 0, totalHeight = 0;
// 行的间距
private int hangJiJian = 20;
// 列的间距
private int lieJianJu = 20;
// 大的布局到四边的距离
private int leftJianJu = 20, rightJianJu = 20, topJianJu = 20,
bottomJianJu = 20;
// 是否已经添加Add选项
private boolean isTianJiaAdd = false;
// 数据的集合
private List<String> list = new ArrayList<String>();
public FlowView(Context context, AttributeSet attrs, int defStyleAttr,
int defStyleRes) {
this(context, attrs);
}
public FlowView(Context context, AttributeSet attrs, int defStyleAttr) {
this(context, attrs);
}
public FlowView(Context context, AttributeSet attrs) {
super(context, attrs);
final TypedArray typedArray = context.obtainStyledAttributes(attrs,
R.styleable.FlowView);
itemLayout = typedArray.getResourceId(R.styleable.FlowView_itemLayout,
R.layout.flow_item_layout);
addLayout = typedArray.getResourceId(R.styleable.FlowView_addLayout,
R.layout.flow_add_layout);
leftJianJu = (int) typedArray.getDimension(R.styleable.FlowView_pLeft,
(int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,
leftJianJu, getResources().getDisplayMetrics()));
rightJianJu = (int) typedArray.getDimension(
R.styleable.FlowView_pRight, (int) TypedValue.applyDimension(
TypedValue.COMPLEX_UNIT_DIP, rightJianJu,
getResources().getDisplayMetrics()));
topJianJu = (int) typedArray.getDimension(R.styleable.FlowView_pTop,
(int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,
topJianJu, getResources().getDisplayMetrics()));
bottomJianJu = (int) typedArray.getDimension(
R.styleable.FlowView_pBottom, (int) TypedValue.applyDimension(
TypedValue.COMPLEX_UNIT_DIP, bottomJianJu,
getResources().getDisplayMetrics()));
hangJiJian = (int) typedArray.getDimension(R.styleable.FlowView_hDiver,
(int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,
hangJiJian, getResources().getDisplayMetrics()));
lieJianJu = (int) typedArray.getDimension(R.styleable.FlowView_lDiver,
(int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,
lieJianJu, getResources().getDisplayMetrics()));
typedArray.recycle();
}
public FlowView(Context context) {
this(context, null);
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
int widthSize = MeasureSpec.getSize(widthMeasureSpec);
int heightSize = MeasureSpec.getSize(heightMeasureSpec);
// int widthMode = MeasureSpec.getMode(widthMeasureSpec);
// int heightMode = MeasureSpec.getMode(heightMeasureSpec);
totalWidth = widthSize;
totalHeight = heightSize;
measureChildren(widthMeasureSpec, heightMeasureSpec);
setMeasuredDimension(widthSize, heightSize);
}
@Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
int count = getChildCount();
// x点的坐标
int xp = leftJianJu, yp = topJianJu;
for (int i = 0; i < count; i++) {
View childView = getChildAt(i);
int cw = childView.getMeasuredWidth();
int ch = childView.getMeasuredHeight();
int xl = 0, xt = 0, xr = 0, xb = 0;
if (xp + cw + hangJiJian + rightJianJu >= totalWidth) {
// 跳转到下一行
yp += ch + lieJianJu;
xp = leftJianJu;
}
if (count - 1 == i && isTianJiaAdd) {
// 正常情况下,在有add的时候添加add选项
xl = totalWidth - rightJianJu - cw;
xt = yp;
xr = xl + cw;
xb = xt + ch;
} else {
// 正常情况下
xl = xp;
xt = yp;
xr = xl + cw;
xb = xt + ch;
}
xp += cw + hangJiJian;
childView.layout(xl, xt, xr, xb);
}
}
// 添加默认的布局
public void addView(String message, int type) {
int layout = 0;
if (type == 1) {
// 正常的item
layout = itemLayout;
} else if (type == 2) {
// add功能按键只能够添加一次
if (isTianJiaAdd) {
return;
}
// 最后一项
isTianJiaAdd = true;
layout = addLayout;
}
RelativeLayout relativeLayout = (RelativeLayout) View.inflate(
getContext(), layout, null);
TextView textView = (TextView) relativeLayout
.findViewById(R.id.textView1);
textView.setLines(1);
textView.setEllipsize(TextUtils.TruncateAt.END);
textView.setMaxLines(1);
textView.setText(message);
relativeLayout.setOnClickListener(this);
if (type == 1) {
relativeLayout.setTag(list.size());
relativeLayout.setId(123);
} else {
relativeLayout.setTag(123);
relativeLayout.setId(123);
}
if (isTianJiaAdd && type == 1) {
addView(relativeLayout, list.size() - 1);
list.add(list.size() - 1, message);
} else {
addView(relativeLayout);
list.add(message);
}
requestLayout();
}
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
switch (v.getId()) {
case 123:
int position = (Integer) v.getTag();
if (position == 123) {
if (onClickFlowView != null) {
onClickFlowView.onClickAdd();
}
} else {
if (onClickFlowView != null) {
onClickFlowView.onClickItem(position, list.get(position));
}
}
break;
default:
break;
}
}
public interface OnClickFlowView {
public void onClickAdd();
public void onClickItem(int position, String message);
}
private OnClickFlowView onClickFlowView;
// ----------
public void setOnClickFlowView(OnClickFlowView onClickFlowView) {
this.onClickFlowView = onClickFlowView;
}
public void setPLeft(int PLeft) {
this.leftJianJu = PLeft;
this.requestLayout();
}
public void setPRight(int PRight) {
this.leftJianJu = PRight;
this.requestLayout();
}
public void setPTop(int PTop) {
this.leftJianJu = PTop;
this.requestLayout();
}
public void setPBottom(int PBottom) {
this.leftJianJu = PBottom;
this.requestLayout();
}
public void setHDiver(int hDiver) {
this.leftJianJu = hDiver;
this.requestLayout();
}
public void setLDiver(int lDiver) {
this.leftJianJu = lDiver;
this.requestLayout();
}
}
4,MainActivity的实现
package com.example.flowingdemo;
import com.example.flowingdemo.view.FlowView;
import com.example.flowingdemo.view.FlowView.OnClickFlowView;
import android.app.Activity;
import android.os.Bundle;
import android.widget.Toast;
public class MainActivity extends Activity implements OnClickFlowView {
private FlowView flowview;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
super.setContentView(R.layout.activity_main);
flowview = (FlowView) findViewById(R.id.flowview);
flowview.setOnClickFlowView(this);
for (int i = 0; i < 10; i++) {
String s = "";
for (int j = 0; j < i; j++) {
s += String.valueOf(j);
}
flowview.addView("i->" + s + i, 1);
}
//添加add选项
flowview.addView("add", 2);
}
@Override
public void onClickAdd() {
flowview.addView("moren", 1);
}
@Override
public void onClickItem(int position, String message) {
Toast.makeText(this, "position=" + position + "-------->" + message,
Toast.LENGTH_SHORT).show();
}
}
源代码的下载地址