XML:
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout 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”
tools:context=".MainActivity">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
>
<EditText
android:id="@+id/edit"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="请输入"
/>
<Button
android:id="@+id/button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="添加"
android:layout_gravity="center_horizontal"
/>
<com.example.flow_nan.FlowLinearLayout
android:id="@+id/flowlayout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginTop="25dp"
></com.example.flow_nan.FlowLinearLayout>
</LinearLayout>
</android.support.constraint.ConstraintLayout>
MainActivity:
package com.example.flow_nan;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
/**
-
@author lenovo
-
输入文本,点击按钮,文本展示在流式布局
*/
public class MainActivity extends AppCompatActivity {
/*定义变量
*
/
EditText edit;
Button button;
FlowLinearLayout flowLinearLayout;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
/
* 获取资源ID
*/
edit=findViewById(R.id.edit);
button=findViewById(R.id.button);
flowLinearLayout=findViewById(R.id.flowlayout);//点击事件 button.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { //得到输入的文本 String string = edit.getText().toString(); //添加到文本视图 TextView view=new TextView(MainActivity.this); view.setText(string); //将文本视图添加到流式布局 flowLinearLayout.addView(view); } });
}
}
FlowLinearLayout:
package com.example.flow_nan;
import android.content.Context;
import android.support.annotation.Nullable;
import android.util.AttributeSet;
import android.view.View;
import android.widget.LinearLayout;
/**
- @author lenovo
- 在流式布局中,
- 1.是否需要换行:
-
根据添加的每个文本的宽与屏幕推荐宽对比,来确定
- 2.每行的高:
-
根据添加的每个文本的高,来确定(不可高过屏幕推荐高)
/
public class FlowLinearLayout extends LinearLayout {
/*
* @param context
*
* 初始化屏幕的起始位置、
* 文本的最大高度
* 文本间左右、上下间隔(单位px)、
*/
int left=0,top=0;
int mTextHeight;
int mHSpace=20,mVSpace=20;
public FlowLinearLayout(Context context) {
super(context);
}
public FlowLinearLayout(Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
}
/*
*寻找文本中最大高度
*/
private void FindMaxTextHeight(){
//定义初始高为0
mTextHeight=0;
//得到所有的文本
int textCount = getChildCount();
for (int i = 0; i <textCount ; i++) {
//得到文本当前的视图
View textView = getChildAt(i);
//如果当前文本的高>初始高
if (textView.getMeasuredHeight()>mTextHeight){
//把当前高当做初始高
mTextHeight=textView.getMeasuredHeight();
}
}
}
/**
* 测量文本的大小,确定是否换行以及高度
* @param widthMeasureSpec
* @param heightMeasureSpec
*/
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
//测量出屏幕最大宽高
int sizeWidth = MeasureSpec.getSize(widthMeasureSpec);
int sizeHeight = MeasureSpec.getSize(heightMeasureSpec);
//测量出每行的宽高!!!!!!(让每个子布局只有一行)
measureChildren(widthMeasureSpec,heightMeasureSpec);
//给出文本的高
FindMaxTextHeight();
int left=0;top=0;
//得到所有的文本
int textCount = getChildCount();
for (int i = 0; i <textCount ; i++) {
//得到当前文本视图
View view = getChildAt(i);
if (left!=0){
//根据文本的宽和当前屏幕宽度的值<===>屏幕宽度比较
if (left+(view.getMeasuredWidth())>sizeWidth){
//换行---确定行高(最高文本+每行间隔)
top+=mTextHeight+mVSpace;
//每次换行,起始left位0
left=0;
}
}
//此时屏幕起始位置改变
left+=view.getMeasuredWidth()+mHSpace;
//屏幕的宽高发生改变--为实际宽高
//在onMeasure(int, int)中,
// 必须调用setMeasuredDimension(int width, int height)来存储测量得到的宽度和高度值,
// 如果没有这么去做会触发异常IllegalStateException。
// (top=0)
setMeasuredDimension(sizeWidth,sizeHeight>(top+mTextHeight)?top+mTextHeight:sizeHeight);
}
}
/**
* 布局文本
* @param changed:
* @param l:相对于父view的Left位置
* @param t:相对于父view的Top位置
* @param r:相对于父view的Right位置
* @param b:相对于父view的Bottom位置
*/
@Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
super.onLayout(changed, l, t, r, b);
int left=0,top=0;
//得到文本的宽和高
FindMaxTextHeight();
int textCount = getChildCount();
for (int i = 0; i <textCount ; i++) {
View view = getChildAt(i);
if (left!=0){
//换行
if (left+(view.getMeasuredWidth())>getWidth()){
top+=mTextHeight+mVSpace;
left=0;
}
}
//文本相对于屏幕的位置
view.layout(left,top,left+view.getMeasuredWidth(),top+mTextHeight);
left+=view.getMeasuredWidth()+mHSpace;
}
}
}