流式布局实现了跟下图类似的功能
流式布局实现是根据自定义View的基础上
那么我们如何实现该图片的效果呢?
下面展示代码
我们需要创建一个View类继承LinearLayout
自定义View里边还需要我们设置子的LinearLayout和一个TextView
因为我们实现的效果是一个大的LinearLayout里边有一行一行小的LinearLayout
在小的LinearLayout里边添加TextView,然后添加数据实现该效果
看一下我们自定义View类的代码
public class View_LS_List extends LinearLayout {
private int mScreenWidth;
public View_LS_List(Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
DisplayMetrics metrics = context.getResources().getDisplayMetrics();
mScreenWidth = metrics.widthPixels;
//设置这个布局垂直显示
setOrientation(VERTICAL);
}
public void removeChildView() {
//移除所有子控件
removeAllViews();
}
public void setData(List<String> data) {
LinearLayout linearLayout = initLearLayouy();//[lvxx,lxs,lzs,lzzs]
for (int i = 0; i < data.size(); i++) {//lvxx
String tmp = data.get(i);
int numWidth = 0;
//得到一行LinearLayout到底有多少子控件 因为我要计算每个子控件加在一起的宽度
int childCount = linearLayout.getChildCount();
//这个for循环只是计算一行LinearLayout的所有子控件的宽的和
for (int j = 0; j < childCount; j++) {
//通过index得到每一个子控件
TextView tv = (TextView) linearLayout.getChildAt(j);
LayoutParams layoutParams = (LayoutParams) tv.getLayoutParams();
int leftMargin = layoutParams.leftMargin;
//测量这个tv的高和宽
tv.measure(getMeasuredWidth(), getMeasuredHeight());
numWidth += tv.getMeasuredWidth() + leftMargin+tv.getPaddingLeft()+getPaddingRight();
}
TextView dataText = initText();
//设置属性
LayoutParams params = new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
params.leftMargin = 10;
params.topMargin = 2;
dataText.setLayoutParams(params);
dataText.setText(tmp);
dataText.measure(getMeasuredWidth(), getMeasuredHeight());
int dataTextWidth = dataText.getMeasuredWidth()+dataText.getPaddingLeft()+dataText.getPaddingRight();
//考虑到一个字符串很长 就直接超过整个屏幕的高了
if (dataTextWidth>=mScreenWidth){
String s = tmp.substring(0, 4);
dataText.setText(s+"...");
dataText.measure(getMeasuredWidth(), getMeasuredHeight());
dataTextWidth = dataText.getMeasuredWidth();
}
//当TextView放满整一行的时候我们需要重新创建一个子LinearLayout重新放置TextView
if (mScreenWidth >= numWidth + dataTextWidth) {
linearLayout.addView(dataText);
} else {
//这里面对LinearLayout重新赋值 通过getLin换行
linearLayout = initLearLayouy();
linearLayout.addView(dataText);
}
}
}
//初始化TextView
private TextView initText() {
TextView textView = new TextView(getContext());
textView.setTextSize(20);
textView.setTextColor(Color.BLACK);
//引用XML实现TextView带边框
textView.setBackgroundResource(R.drawable.text_shape);
textView.setPadding(10,10,10,10);
return textView;
}
//初始化子LinearLayout
private LinearLayout initLearLayouy() {
LinearLayout linearLayout = new LinearLayout(getContext());
//LayoutParams 控制组件大小的一个工具类
LayoutParams params = new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT);
linearLayout.setLayoutParams(params);
//this本类对象
this.addView(linearLayout);//只要重新添加View了自动换行了
return linearLayout;
}
}
下面是我的activity_main.xml引用自定义View还有一个搜索框和按钮
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context=".MainActivity">
<EditText
android:id="@+id/ed_text"
android:hint="请输入数据"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<Button
android:id="@+id/ed_btn"
android:text="搜索"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<text.bwie.com.zdyview_lsbj.View_LS_List
android:id="@+id/zdyView"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</LinearLayout>
这里是我的MainActivity调用自定义View里边设置好的方法并传参数
public class MainActivity extends AppCompatActivity implements View.OnClickListener {
private EditText ed_text;
private Button ed_btn;
private View_LS_List zdyView;
private List<String> dataAll = new ArrayList<>();
private List<String> newDataAll = new ArrayList<>();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initData();
initView();
zdyView.setData(dataAll);
}
private void initData() {
for (int i = 0; i < 20; i++) {
dataAll.add("sss"+i);
}
}
private void initView() {
ed_text = (EditText) findViewById(R.id.ed_text);
ed_btn = (Button) findViewById(R.id.ed_btn);
zdyView = (View_LS_List) findViewById(R.id.zdyView);
ed_btn.setOnClickListener(this);
}
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.ed_btn:
String trim = ed_text.getText().toString().trim();
zdyView.removeChildView();
newDataAll.add(trim);
zdyView.setData(newDataAll);
zdyView.setData(dataAll);
break;
}
}
}
到这里就可以实现如上图所展示的效果,数据自拟
上面这个传入的集合,那么下面传入一个String字符串处理的方法
public class View_LS_List extends LinearLayout {
private int mScreenWidth;
public View_LS_List(Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
DisplayMetrics metrics = context.getResources().getDisplayMetrics();
mScreenWidth = metrics.widthPixels;
//设置这个布局垂直显示
setOrientation(VERTICAL);
}
public void removeChildView() {
//移除所有子控件
removeAllViews();
}
public void setData(List<String> data) {
LinearLayout linearLayout = initLearLayouy();//[lvxx,lxs,lzs,lzzs]
for (int i = 0; i < data.size(); i++) {//lvxx
String tmp = data.get(i);
int numWidth = 0;
//得到一行LinearLayout到底有多少子控件 因为我要计算每个子控件加在一起的宽度
int childCount = linearLayout.getChildCount();
//这个for循环只是计算一行LinearLayout的所有子控件的宽的和
for (int j = 0; j < childCount; j++) {
//通过index得到每一个子控件
TextView tv = (TextView) linearLayout.getChildAt(j);
LayoutParams layoutParams = (LayoutParams) tv.getLayoutParams();
int leftMargin = layoutParams.leftMargin;
//测量这个tv的高和宽
tv.measure(getMeasuredWidth(), getMeasuredHeight());
numWidth += tv.getMeasuredWidth() + leftMargin+tv.getPaddingLeft()+getPaddingRight();
}
TextView dataText = initText();
//设置属性
LayoutParams params = new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
params.leftMargin = 10;
params.topMargin = 2;
dataText.setLayoutParams(params);
dataText.setText(tmp);
dataText.measure(getMeasuredWidth(), getMeasuredHeight());
int dataTextWidth = dataText.getMeasuredWidth()+dataText.getPaddingLeft()+dataText.getPaddingRight();
//考虑到一个字符串很长 就直接超过整个屏幕的高了
if (dataTextWidth>=mScreenWidth){
String s = tmp.substring(0, 4);
dataText.setText(s+"...");
dataText.measure(getMeasuredWidth(), getMeasuredHeight());
dataTextWidth = dataText.getMeasuredWidth();
}
//当TextView放满整一行的时候我们需要重新创建一个子LinearLayout重新放置TextView
if (mScreenWidth >= numWidth + dataTextWidth) {
linearLayout.addView(dataText);
} else {
//这里面对LinearLayout重新赋值 通过getLin换行
linearLayout = initLearLayouy();
linearLayout.addView(dataText);
}
}
}
//初始化TextView
private TextView initText() {
TextView textView = new TextView(getContext());
textView.setTextSize(20);
textView.setTextColor(Color.BLACK);
//引用XML实现TextView带边框
textView.setBackgroundResource(R.drawable.text_shape);
textView.setPadding(10,10,10,10);
return textView;
}
//初始化子LinearLayout
private LinearLayout initLearLayouy() {
LinearLayout linearLayout = new LinearLayout(getContext());
//LayoutParams 控制组件大小的一个工具类
LayoutParams params = new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT);
linearLayout.setLayoutParams(params);
//this本类对象
this.addView(linearLayout);//只要重新添加View了自动换行了
return linearLayout;
}
}
到这里就是我的全部代码,如果还有不太清楚的地方可以参考一下代码
地址:https://github.com/qq1341738311/Fluid-layout-Demo