SeniorUI0201

xiaoxiao2021-02-28  49

高级UI汇总目录 SeniorUI02_UI绘制流程分析二(View的绘制过程)

一、 Demo地址

FlowLayout

二、Effect picture

三、requireMent

定义一个容器,可以添加标签标签高度不确定,左对齐,上对齐每个标签可以自定义大小、背景,可以点击

四、Theory

自定义ViewGroup实现容器 2)通过自定ViewGroup的onMesure和onLayout方法,来控制容器的大小和标签的位置 3)一个标签表示一个View,可以addView或xml中设置;ViewGroup中遍历获取,并设置点击事件

五、CoreCode

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); } //通过child,设置容器的大小,并记录View的摆放信息 @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { super.onMeasure(widthMeasureSpec, heightMeasureSpec); // 获取父容器为FlowLayout设置的测量模式和大小 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 iChildWidth; int iChildHeight; int childCount = getChildCount(); List<View> viewList = new ArrayList<>(); mViewLinesList.clear(); mLineHeights.clear(); 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 (iCurLineW + iChildWidth > iWidthSpecSize) { /**1、记录当前行的信息***/ //1、记录当前行的最大宽度,高度累加 measuredWith = Math.max(measuredWith, iCurLineW); measuredHeight += iCurLineH; //2、将当前行的viewList添加至总的mViewsList,将行高添加至总的行高List mViewLinesList.add(viewList); mLineHeights.add(iCurLineH); /**2、记录新一行的信息***/ //1、重新赋值新一行的宽、高 iCurLineW = iChildWidth; iCurLineH = iChildHeight; // 2、新建一行的viewlist,添加新一行的view viewList = new ArrayList<View>(); viewList.add(childView); } else { // 记录某行内的消息 //1、行内宽度的叠加、高度比较 iCurLineW += iChildWidth; iCurLineH = Math.max(iCurLineH, iChildHeight); // 2、添加至当前行的viewList中 viewList.add(childView); } /*****3、如果正好是最后一行需要换行**********/ if (i == childCount - 1) { //1、记录当前行的最大宽度,高度累加 measuredWith = Math.max(measuredWith, iCurLineW); measuredHeight += iCurLineH; //2、将当前行的viewList添加至总的mViewsList,将行高添加至总的行高List mViewLinesList.add(viewList); mLineHeights.add(iCurLineH); } } } // 最终目的 setMeasuredDimension(measuredWith, measuredHeight); } /** * 根据View的摆放信息,设置View的位置 **/ @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); } } 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); } }); } } }

使用

转载请注明原文地址: https://www.6miu.com/read-2612426.html

最新回复(0)