1. 程式人生 > >根據輸入文字的寬高進行流式佈局

根據輸入文字的寬高進行流式佈局

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;
    }
}

}