Android之FlowLayout流式布局
来源:互联网 发布:手机淘宝在线客服人工 编辑:程序博客网 时间:2024/04/29 07:13
传承者(Inheritors)打造共同进步生态圈!!!
转载:http://blog.csdn.net/lmj623565791/article/details/38352503
考虑宽高,设置宽高是重点
flag_04
<?xml version="1.0" encoding="utf-8"?><shape xmlns:android="http://schemas.android.com/apk/res/android" > <solid android:color="#7690A5" > </solid> <corners android:radius="5dp"/> <padding android:bottom="2dp" android:left="10dp" android:right="10dp" android:top="2dp" /></shape>
main
<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" tools:context="com.example.administrator.testapplication.Main2Activity"><com.example.administrator.testapplication.FlowLayout android:layout_width="match_parent" android:layout_height="wrap_content" > <TextView style="@style/text_flag_01" android:background="@drawable/flag_04" android:text="Welcome" android:textColor="#323232" /> <TextView style="@style/text_flag_01" android:background="@drawable/flag_04" android:text="IT工程师" android:textColor="#323232" /> <TextView style="@style/text_flag_01" android:background="@drawable/flag_04" android:text="学习ing" android:textColor="#323232" /> <TextView style="@style/text_flag_01" android:background="@drawable/flag_04" android:text="恋爱ing" android:textColor="#323232" /> <TextView style="@style/text_flag_01" android:background="@drawable/flag_04" android:text="挣钱ing" android:textColor="#323232" /> <TextView style="@style/text_flag_01" android:background="@drawable/flag_04" android:text="努力ing" android:textColor="#323232" /> <TextView style="@style/text_flag_01" android:background="@drawable/flag_04" android:text="I thick i can" android:textColor="#323232" /> <TextView style="@style/text_flag_01" android:background="@drawable/flag_04" android:text="dddddd" android:textColor="#323232" /> <TextView style="@style/text_flag_01" android:background="@drawable/flag_04" android:text="黑恶黑诶诶" android:textColor="#323232" /> <TextView style="@style/text_flag_01" android:background="@drawable/flag_04" android:text="I thick i can" android:textColor="#323232" /></com.example.administrator.testapplication.FlowLayout></LinearLayout>
style
<style name="text_flag_01"> <item name="android:layout_width" >wrap_content</item> <item name="android:layout_height">wrap_content</item> <item name="android:layout_margin">4dp</item> <item name="android:background">@drawable/flag_01</item> <item name="android:textColor">#ffffff</item> </style>
FlowLayout
public class FlowLayout extends ViewGroup{ 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) { super.onMeasure(widthMeasureSpec, heightMeasureSpec); //获得它的父容器为它设置的测量模式和大小 int sizeWidth = MeasureSpec.getSize(widthMeasureSpec); int sizeHeight = MeasureSpec.getSize(heightMeasureSpec); int modeWidth = MeasureSpec.getMode(widthMeasureSpec); int modeHeight = MeasureSpec.getMode(heightMeasureSpec); //如果wrap_content情况下,记录宽和高 int width =0, height = 0; //记录每一行的宽度,width不断取最大的宽度 int lineWidth = 0; //每一行的高度,累计至height int lineHeight = 0; int cCount = getChildCount(); //遍历每个子元素 for (int i = 0; i < cCount; i++) { View child = getChildAt(i); //测量每一个child的宽和高 measureChild(child,widthMeasureSpec,heightMeasureSpec); //得到child的lp MarginLayoutParams lp = (MarginLayoutParams) child.getLayoutParams(); //当前子空间实际占据的宽度 int childWidth = child.getMeasuredWidth()+lp.leftMargin + lp.rightMargin; int childHeight = child.getMeasuredHeight()+lp.topMargin +lp.bottomMargin; //如果加入当前child,则超出最大宽度,则给目前最大宽度,启动新的一行 if(lineWidth +childWidth>sizeWidth){ width = Math.max(lineWidth,childWidth);//获取最大的 lineWidth = childWidth;//重新开启新的行,开始记录 //叠加当前高度 height+= lineHeight; //开启记录下一行的高度 lineHeight = childHeight; }else{ //否则累加值lineWidth,lineHeight取最大高度 lineWidth+=childWidth; lineHeight = Math.max(lineHeight, childHeight); } //如果是最后一个,则将当前记录得最大宽度和当前lineWidth做比较 if(i == cCount - 1){ width = Math.max(width, lineWidth); height+=lineHeight; } } setMeasuredDimension((modeWidth == MeasureSpec.EXACTLY )? sizeWidth:width,(modeHeight == MeasureSpec.EXACTLY )? sizeHeight:height); } /** * 存储所有的view * 按行记录 * */ private List<List<View>> mAllViews = new ArrayList<>(); //记录每一行的最大高度 private List<Integer> mLineHeight = new ArrayList<>(); @Override protected void onLayout(boolean changed, int l, int t, int r, int b) { mAllViews.clear(); mLineHeight.clear(); int width = getWidth(); int lineWidth = 0,lineHeight = 0; // 存储每一行所有的childView List<View> lineViews = new ArrayList<>(); int cCount = getChildCount(); //遍历所有的孩子 for (int i = 0; i < cCount; i++) { View child = getChildAt(i); MarginLayoutParams lp = (MarginLayoutParams) child.getLayoutParams(); int childWidth = child.getMeasuredWidth(); int childHeight = child.getMeasuredHeight(); //如果 需要换行 if(childWidth +lp.leftMargin + lp.rightMargin+lineWidth > width){ //记录这一行所有的View 以及最大的高度 mLineHeight.add(lineHeight); //将当前的childView保存,然互开启新的ArrayList保存下一行的childView mAllViews.add(lineViews); lineWidth = 0;//重置行宽 lineViews = new ArrayList<>(); } //如果不需要换行,则累加 lineWidth += childWidth + lp.leftMargin+ lp.rightMargin; lineHeight = Math.max(lineHeight, childHeight + lp.topMargin + lp.bottomMargin); lineViews.add(child); } //记录最后一行 mLineHeight.add(lineHeight); mAllViews.add(lineViews); int left =0, top = 0; //得到总行数 int lineNums = mAllViews.size(); for (int i = 0; i < lineNums; i++) { //每一行的所有的views lineViews = mAllViews.get(i); //当前行的最大高度 lineHeight = mLineHeight.get(i); //遍历当前所有的view for (int j = 0; j < lineViews.size(); j++) { View child = lineViews.get(j); if(child.getVisibility() == View.GONE){ continue; } MarginLayoutParams lp = (MarginLayoutParams) child.getLayoutParams(); //计算childView 的left,top,right,bottom int lc = left + lp.leftMargin; int tc =top+lp.topMargin; int rc = lc + child.getMeasuredWidth(); int bc = tc + child.getMeasuredHeight(); child.layout(lc,tc,rc,bc); left += child.getMeasuredWidth() + lp.rightMargin + lp.leftMargin; } left = 0; top += lineHeight; } }}
效果
0 0
- Android之FlowLayout流式布局
- Android 流式布局FlowLayout
- Android流式布局-FlowLayout
- Android流式布局FlowLayout
- Android:FlowLayout流式布局
- Android FlowLayout 流式布局
- Android轻松实现流式布局之FlowLayout
- 自定义控件之-流式布局FlowLayout
- 流式布局之FlowLayout使用
- Android自定义流式布局-FlowLayout
- android 实现流式布局FlowLayout
- Android自定义流式布局-FlowLayout
- Android开发流式布局FlowLayout
- Android自定义控件--流式布局(FlowLayout)
- FlowLayout流式布局
- FlowLayout流式布局
- 流式布局FlowLayout
- 流式布局FlowLayout
- Android初级教程理论知识(第八章网络编程二)
- gem下安装sass错误
- 1、RedHat6 HA集群理论与环境
- 实时监控、直播流、流媒体、视频网站开发方案设计简要
- Android 设置中的蓝牙
- Android之FlowLayout流式布局
- Lua笔记 & 与C之间的交互
- 缩放ImageView
- C++网络编程服务器select模型(参考)
- mysql 批量更改符合指定条件的记录的主键为一系列值
- 字符的左右移动-java
- 安卓自定义搜索框(searchview)
- Python3 简介
- 关系数据库(范式判断、函数依赖、无损分解、正则覆盖)