Android流式布局
来源:互联网 发布:网络销售自我评价 编辑:程序博客网 时间:2024/06/07 21:54
import android.content.Context;import android.util.AttributeSet;import android.view.View;import android.view.ViewGroup;import java.util.ArrayList;import java.util.List;/** * 流式布局 * * 用法 * 1、可以直接当做一个父布局使用 类似LinearLayout在布局中给其添加布局 * 2、如果在代码中添加布局 需要给需要添加的child设置MarginLayoutParams 例如下面是添加一个TextView的例子 * 需要在代码中设置TextView的宽高 和margin值 * * 例子: * TextView textView = new TextView(this); * ViewGroup.MarginLayoutParams marginLayoutParams * = new ViewGroup.MarginLayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, * ViewGroup.LayoutParams.WRAP_CONTENT); * textView.setLayoutParams(marginLayoutParams); * flowLayout.addView(textView); * * Created by linyaokui on 2017/11/6. */public class FlowLayout extends ViewGroup { /** * 用来保存每行views的列表 */ private List<List<View>> mViewLinesList; /** * 用来保存行高的列表 */ private List<Integer> mLineHeights; public FlowLayout(Context context) { this(context,null); } public FlowLayout(Context context, AttributeSet attrs) { this(context, attrs,0); } public FlowLayout(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); } @Override public LayoutParams generateLayoutParams(AttributeSet attrs) { return new MarginLayoutParams(getContext(),attrs); } @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { super.onMeasure(widthMeasureSpec, heightMeasureSpec); mViewLinesList = new ArrayList<>(); mLineHeights = new ArrayList<>(); // 获取父容器为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; //当前行的高度 int iChildWidth; int iChildHeight; int childCount = getChildCount(); 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(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<>(); 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); } } if(iWidthMode == MeasureSpec.EXACTLY ){ measuredWith = iWidthSpecSize; } if(iHeightMode == MeasureSpec.EXACTLY){ measuredHeight = iHeightSpecSize;} 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); } }); } }}
阅读全文
0 0
- Android流式布局
- Android 流式布局
- Android流式布局
- Android流式布局
- Android流式布局
- Android流式布局
- android流式布局
- Android 流式布局FlowLayout
- Android流式布局实现
- Android流式布局-FlowLayout
- Android流式布局实现
- Android 自定义流式布局
- Android流式布局实现
- Android流式布局实现
- android流式布局控件
- Android流式布局FlowLayout
- Android:FlowLayout流式布局
- Android 流式布局LinearLayout
- Pandas 数据集合并
- Ubuntu下安装Java
- C++实战之OpenCL矩阵相乘
- swift 弹幕碰撞检测
- Eclipse导出Maven项目生成war包的两种办法
- Android流式布局
- 海明校验码
- 深入解析js中基本数据类型与引用类型,函数参数传递的区别
- ActiveMQ (二) 常用配置简介
- Druid更新版本后,报错skip not validate connection
- WebService学习总结:java使用JDK发布和调用WebService(转载)
- python字典列表实例
- Python+selenium右键菜单不管用的解决办法
- Mui中在关闭子页面的时候同时关闭父页面