import android.content.Context; import android.util.AttributeSet; import android.view.View; import android.view.ViewGroup; import java.util.ArrayList; import java.util.List; /** * Created by lpq on 2017/7/13. */ public class FlowLayout extends ViewGroup { /** * 用来保存每行views的列表 */ private List<List<View>> mViewLinesList = new ArrayList<>(); /** * 用来保存行高的列表 */ private List<Integer> mLineHeights = new ArrayList<>(); public FlowLayout(Context context, AttributeSet attrs) { super(context, attrs); } @Override public LayoutParams generateLayoutParams(AttributeSet attrs) { return new MarginLayoutParams(getContext(), attrs); } @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { super.onMeasure(widthMeasureSpec, heightMeasureSpec); // 获取父容器给设置的测量模式和大小 int iWidthMode = MeasureSpec.getMode(widthMeasureSpec); int iHeightMode = MeasureSpec.getMode(heightMeasureSpec); int iWidthSpecSize = MeasureSpec.getSize(widthMeasureSpec); int iHeightSpecSize = MeasureSpec.getSize(heightMeasureSpec); int measuredWith = 0;//总的行宽 int measuredHeight = 0;//总的行高 int iCurLineW = 0;//当前行宽 int iCurLineH = 0;//当前行高 if (iWidthMode == MeasureSpec.EXACTLY && iHeightMode == MeasureSpec.EXACTLY) { measuredWith = iWidthSpecSize; measuredHeight = iHeightSpecSize; } else { int childCount = getChildCount(); int iChildWidth; int iChildHeight; List<View> viewList = new ArrayList<>(); for (int i = 0; i < childCount; i++) { View childView = getChildAt(i); measureChild(childView, widthMeasureSpec, heightMeasureSpec); MarginLayoutParams layoutParams = (MarginLayoutParams) childView.getLayoutParams(); iChildWidth = childView.getMeasuredWidth() + layoutParams.leftMargin + layoutParams.rightMargin; iChildHeight = childView.getMeasuredHeight() + layoutParams.topMargin + layoutParams.bottomMargin; if (iChildWidth + iCurLineW > iWidthSpecSize) { //换行 measuredWith = Math.max(iCurLineW, measuredWith); measuredHeight += iCurLineH; mViewLinesList.add(viewList); mLineHeights.add(iCurLineH); //重新设置当前行宽行高 iCurLineH = iChildHeight; iCurLineW = iChildWidth; viewList = new ArrayList<>(); viewList.add(childView); } else { //不换行,记录当前行宽和行高 iCurLineW += iChildWidth; iCurLineH = Math.max(iCurLineH, iChildHeight); viewList.add(childView); } if(i == childCount - 1){ measuredWith = Math.max(measuredWith,iCurLineW); measuredHeight += iCurLineH; mViewLinesList.add(viewList); mLineHeights.add(iCurLineH); } } } //测量最后必须调用 setMeasuredDimension(measuredWith, measuredHeight); } @Override protected void onLayout(boolean changed, int l, int t, int r, int b) { int left, top, right, bottom; int curTop = 0; int curLeft = 0; int lineCount = mViewLinesList.size(); for (int i = 0; i < lineCount; i++) { List<View> viewList = mViewLinesList.get(i); int lineViewSize = viewList.size(); for (int j = 0; j < lineViewSize; j++) { View childView = viewList.get(j); MarginLayoutParams layoutParams = (MarginLayoutParams) childView.getLayoutParams(); left = curLeft + layoutParams.leftMargin; top = curTop + layoutParams.topMargin; right = left + childView.getMeasuredWidth(); bottom = top + childView.getMeasuredHeight(); childView.layout(left, top, right, bottom); curLeft += childView.getMeasuredWidth() + layoutParams.leftMargin + layoutParams.rightMargin; } curLeft = 0; curTop += mLineHeights.get(i); } mViewLinesList.clear(); mLineHeights.clear(); } public interface OnItemClickListener{ void onItemClick (View v, int index); } public void setOnItemClickListener(final OnItemClickListener listener){ int childCount = getChildCount(); for(int i = 0 ; i < childCount ; i++){ View childView = getChildAt(i); final int finalI = i; childView.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { listener.onItemClick(v, finalI); } }); } } }
Android 流式布局之自动换行
最新推荐文章于 2024-07-13 23:11:02 发布