日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > Android >内容正文

Android

android 换行乱_Android自动换行布局

發布時間:2025/3/11 Android 29 豆豆
生活随笔 收集整理的這篇文章主要介紹了 android 换行乱_Android自动换行布局 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

public class FlowLayout extends ViewGroup {

/**

* 所有子控件的容器

*/

private List> lineList = new ArrayList<>();

/**

* 每行的高度

*/

private List lineHeightList = new ArrayList<>();

/**

* 防止多次測量

*/

private boolean measureFlag = true;

public FlowLayout(Context context) {

super(context);

}

public FlowLayout(Context context, AttributeSet attrs) {

super(context, attrs);

}

public FlowLayout(Context context, AttributeSet attrs, int defStyleAttr) {

super(context, attrs, defStyleAttr);

}

@Override

public LayoutParams generateLayoutParams(AttributeSet attrs) {

return new MarginLayoutParams(getContext(), attrs);

}

/**

* 在被調用這個方法之前 它的父容器 已經把它的測量模式改成了當前控件的測量模式

*

* @param widthMeasureSpec

* @param heightMeasureSpec

*/

@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);

//記錄當前控件里面的子控件的總高寬

int childMaxWidth = 0;

int childCountHeight = 0;

//防止多次測量

if (measureFlag) {

measureFlag = false;

} else {

//當前一行,控件中的子控件的總寬度

int lineCountWidth = 0;

//當前一行,最高子控件的高度

int lineMaxHeight = 0;

//記錄每個子控件的寬高

int childWidth, childHeight;

//創建一行空容器

List viewList = new ArrayList<>();

int childCount = getChildCount();

for (int i = 0; i < childCount; i++) {

View childView = getChildAt(i);

//先測量子控件

measureChild(childView, widthMeasureSpec, heightMeasureSpec);

MarginLayoutParams layoutParams = (MarginLayoutParams) childView.getLayoutParams();

//計算當前子控件的實際寬高

childWidth = childView.getMeasuredWidth() + layoutParams.leftMargin + layoutParams.rightMargin;

childHeight = childView.getMeasuredHeight() + layoutParams.topMargin + layoutParams.bottomMargin;

//如果當前行的寬度,加上這個view的寬度,大于容器的寬度時,就換行

if (lineCountWidth + childWidth + getPaddingLeft() + getPaddingRight() > widthSize) {

//需要換行的情況

//每次進入到這里的時候 只是保存了上一行的信息,并沒有保存當前行的信息

//拿到所有行中,最大的寬,去決定EXACTLY時的最大寬度

childMaxWidth = Math.max(childMaxWidth, lineCountWidth);

childCountHeight += lineMaxHeight;

//把行高記錄到集合中

lineHeightList.add(lineMaxHeight);

//把這一行的數據放進總容器

lineList.add(viewList);

//把一行的容器,重新創建一個,雖然會頻繁創建,但如果調用clear,會導致lineList的棧也會被清掉

viewList = new ArrayList<>();

//把每行的高寬初始化

lineCountWidth = childWidth;

lineMaxHeight = childHeight;

viewList.add(childView);

} else {

//不需要換行的情況

lineCountWidth += childWidth;

//取當前行的所有子控件最大的高度

lineMaxHeight = Math.max(lineMaxHeight, childHeight);

viewList.add(childView);

}

//這樣做的原因是 之前的if else中 不會把最后一行的高度加進listLineHeight

// 最后一行要特殊對待 不管最后一個item是不是最后一行的第一個item

if (i == (childCount - 1)) {

//保存當前行信息

childMaxWidth = Math.max(childMaxWidth, lineCountWidth + getPaddingLeft() + getPaddingRight());

childCountHeight += lineMaxHeight;

lineHeightList.add(lineMaxHeight);

lineList.add(viewList);

}

}

}

//設置控件最終大小

int measureWidth = (widthMode == MeasureSpec.EXACTLY ? widthSize : childMaxWidth + getPaddingLeft() + getPaddingRight());

int measureHeight = (heightMode == MeasureSpec.EXACTLY ? heightSize : childCountHeight + getPaddingTop() + getPaddingBottom());

setMeasuredDimension(measureWidth, measureHeight);

}

@Override

protected void onLayout(boolean changed, int l, int t, int r, int b) {

//擺放子控件的位置

int left, top, right, bottom;

//保存上一個控件的邊距

int countLeft = 0;

//保存上一行的高度的邊距

int countTop = 0;

//遍歷所有行

for (List views : lineList) {

//遍歷每一行的控件

for (View view : views) {

MarginLayoutParams layoutParams = (MarginLayoutParams) view.getLayoutParams();

left = countLeft + layoutParams.leftMargin;

top = countTop + layoutParams.topMargin;

right = left + view.getMeasuredWidth();

bottom = top + view.getMeasuredHeight();

view.layout(left + getPaddingLeft(), top + getPaddingTop(), right + getPaddingRight(), bottom + getPaddingBottom());

//記錄當前控件的實際寬度坐標,讓下一個控件知道X軸的起點在哪

countLeft += view.getMeasuredWidth() + layoutParams.leftMargin + layoutParams.rightMargin;

}

int i = lineList.indexOf(views);

//換行時從最左邊開始

countLeft = 0;

//換行時累加高度

countTop += lineHeightList.get(i);

}

//布局結束后清空記錄的list

lineList.clear();

lineHeightList.clear();

}

}

總結

以上是生活随笔為你收集整理的android 换行乱_Android自动换行布局的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。