1,自定义flowlayout代码

package com.hyang.administrator.studentproject.widget;import android.content.Context;
import android.util.AttributeSet;
import android.util.Log;
import android.view.View;
import android.view.ViewGroup;import java.util.ArrayList;
import java.util.List;/*** Created by Administrator on 2017/6/20.*/
public class FlowGroupView extends ViewGroup {/*** 储存所有的view 按行记录*/private List<List<View>> mAllViews = new ArrayList<List<View>>();/*** 记录每一行的高度*/private List<Integer> mLineHeight = new ArrayList<Integer>();private String TAG = "TAG";public FlowGroupView(Context context, AttributeSet attrs,int defStyleAttr) {super(context, attrs, defStyleAttr);}public FlowGroupView(Context context, AttributeSet attrs) {super(context, attrs);}public FlowGroupView(Context context) {super(context);}@Overrideprotected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {// 置空 view 容器 和 lineHeight 容器  重新赋值//因为OnMeasure方法会走两次,第一次是实例化这个对象的时候高度和宽度都是0//之后走了OnSizeChange()方法后 又走了一次OnMeasure,所以要把第一次加进去的数据清空。
        mAllViews.clear();mLineHeight.clear();//得到上级容器为其推荐的宽高和计算模式int specWidthMode = MeasureSpec.getMode(widthMeasureSpec);int specHeighMode = MeasureSpec.getMode(heightMeasureSpec);int specWidthSize = MeasureSpec.getSize(widthMeasureSpec);int specHeighSize = MeasureSpec.getSize(heightMeasureSpec);// 计算出所有的 child 的 宽和高
//      measureChildren(specWidthSize, specHeighSize);// 记录如果是 warp_content 是设置的宽和高int width = 0;int height = 0;// 得到子view的个数int cCount = getChildCount();/*** 记录每一行的宽度,width不断取最大宽度*/int lineWidth = 0;/*** 每一行的高度,累加至height*/int lineHeight = 0;// 存储每一行所有的childViewList<View> lineViews = new ArrayList<View>();for (int i = 0; i < cCount; i++) {// 得到每个子ViewView child = getChildAt(i);// 测量每个子View的宽高
            measureChild(child, widthMeasureSpec, heightMeasureSpec);// 当前子view的lpMarginLayoutParams lp = (MarginLayoutParams) child.getLayoutParams();// 子view的宽和高int cWidth = 0;int cheight = 0;// 当前子 view 实际占的宽cWidth = child.getMeasuredWidth() + lp.leftMargin + lp.rightMargin;// 当前子View 实际占的高cheight = child.getMeasuredHeight() + lp.topMargin + lp.bottomMargin;lineHeight=cheight;// 需要换行if(lineWidth + cWidth > specWidthSize){width = Math.max(lineWidth, cWidth);// 取最大值lineWidth = cWidth; // 开启新行的时候重新累加width// 开启新行时累加 height
//              lineHeight = cheight; // 记录下一行的高度
                mAllViews.add(lineViews);mLineHeight.add(cheight);lineViews = new ArrayList<>();// 换行的时候把该 view 放进 集合里lineViews.add(child);// 这个  view(child) 是下一行的第一个viewheight += cheight; //每个View高度是一样的,直接累加Log.e("需要换行", "hight--" + height);Log.e("onMeasure", "AllViews.size()  --  > " + mAllViews.size());}else {// 不需要换行lineWidth += cWidth;//
                Log.e("不需要换行","hight--"+height);// 不需要换行时 把子View add 进集合
                lineViews.add(child);}if(i == cCount-1){// 如果是最后一个viewwidth = Math.max(lineWidth, cWidth);height += cheight;Log.e("最后一个view","hight--"+height);}}// 循环结束后 把最后一行内容add进集合中mLineHeight.add(lineHeight); // 记录最后一行
        mAllViews.add(lineViews);// MeasureSpec.EXACTLY 表示设置了精确的值// 如果 mode 是 MeasureSpec.EXACTLY 时候,则不是 warp_content 用计算来的值,否则则用上级布局分给它的值
        setMeasuredDimension(specWidthMode == MeasureSpec.EXACTLY ? specWidthSize : width,specHeighMode == MeasureSpec.EXACTLY ? specHeighSize : height);Log.e("onMeasure", "mAllViews.size() -- > " + mAllViews.size() + "   mLineHeight.size() -- > " + mLineHeight.size() + "Height -- > "+height);}/*** 所有childView的位置的布局*/@Overrideprotected void onLayout(boolean changed, int l, int t, int r, int b) {// 当前行的最大高度int lineHeight = 0;// 存储每一行所有的childViewList<View> lineViews = new ArrayList<View>();int left = 0;int top = 0;// 得到总行数int lineNums = mAllViews.size();for (int i = 0; i < lineNums; i++){// 每一行的所有的viewslineViews = mAllViews.get(i);// 当前行的最大高度lineHeight = mLineHeight.get(i);Log.e("onLayout" , "第" + i + "行 :" + lineViews.size()+"-------lineHeight"+ lineHeight);// 遍历当前行所有的Viewfor (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,bottomint 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;}Log.v("onLayout", "onLayout   mAllViews.size() -- > " + mAllViews.size() + "   mLineHeight.size() -- > "+ mLineHeight.size());}/*** 这个一定要设置,否则会包强转错误* 设置它支持 marginLayoutParams*/@Overridepublic ViewGroup.LayoutParams generateLayoutParams(AttributeSet attrs) {return new MarginLayoutParams(getContext(),attrs);}
}

2.在布局文件中使用

1 <com.hyang.administrator.studentproject.widget.FlowGroupView
2     android:id="@+id/flow_view_group"
3     android:layout_width="match_parent"
4     android:layout_height="wrap_content">
5 </com.hyang.administrator.studentproject.widget.FlowGroupView>

3.TextView的样式文件

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android" ><solid android:color="#E7E7E7" ></solid><cornersandroid:radius="30dp"/><paddingandroid:bottom="2dp"android:left="10dp"android:right="10dp"android:top="2dp" />
</shape>

4.在Activity中使用

 1 package com.hyang.administrator.studentproject.activity;
 2
 3 import android.graphics.Color;
 4 import android.os.Bundle;
 5 import android.support.v7.app.AppCompatActivity;
 6 import android.view.View;
 7 import android.view.ViewGroup;
 8 import android.widget.Button;
 9 import android.widget.TextView;
10 import android.widget.Toast;
11
12 import com.hyang.administrator.studentproject.R;
13 import com.hyang.administrator.studentproject.widget.FlowGroupView;
14
15 import org.xutils.view.annotation.ViewInject;
16 import org.xutils.x;
17
18 import java.util.ArrayList;
19
20 public class FlowLayoutActivity extends AppCompatActivity {
21
22     @ViewInject(R.id.flow_button)
23     private Button addTextButton;
24     @ViewInject(R.id.flow_view_group)
25     private FlowGroupView flowView;
26
27     private ArrayList<String> names;
28
29
30     @Override
31     protected void onCreate(Bundle savedInstanceState) {
32         super.onCreate(savedInstanceState);
33         setContentView(R.layout.activity_flow_layout);
34         x.view().inject(this);
35
36         setTwoFlowLayout();
37
38         addTextButton.setOnClickListener(new View.OnClickListener() {
39             @Override
40             public void onClick(View v) {
41                 addTextView("添加1");
42             }
43         });
44     }
45
46     private void setTwoFlowLayout() {
47         //添加数据
48         names = new ArrayList<String>();
49         names.add("降龙十八掌");
50         names.add("黯然销魂掌");
51         names.add("左右互搏术");
52         names.add("七十二路空明拳");
53         names.add("小无相功");
54         names.add("拈花指");
55         names.add("打狗棍法");
56         names.add("蛤蟆功");
57         names.add("九阴白骨爪");
58         names.add("一招半式闯江湖");
59         names.add("醉拳");
60         names.add("龙蛇虎豹");
61         names.add("葵花宝典");
62         names.add("吸星大法");
63         names.add("如来神掌警示牌");
64         //为布局添加内容
65         for (int i = 0; i < names.size(); i++) {
66             addTextView(names.get(i));
67         }
68     }
69
70     /**
71      * 动态添加布局
72      * @param str
73      */
74     private void addTextView(String str) {
75         TextView child = new TextView(this);
76         ViewGroup.MarginLayoutParams params = new ViewGroup.MarginLayoutParams(ViewGroup.MarginLayoutParams.WRAP_CONTENT, ViewGroup.MarginLayoutParams.WRAP_CONTENT);
77         params.setMargins(5, 5, 5, 5);
78         child.setLayoutParams(params);
79         child.setBackgroundResource(R.drawable.flag);
80         child.setText(str);
81         child.setTextColor(Color.WHITE);
82         initEvents(child);//监听
83         flowView.addView(child);
84     }
85
86     /**
87      * 为每个view 添加点击事件
88      */
89     private void initEvents(final TextView tv){
90         tv.setOnClickListener(new View.OnClickListener() {
91
92             @Override
93             public void onClick(View v) {
94                 Toast.makeText(FlowLayoutActivity.this, tv.getText().toString(), Toast.LENGTH_SHORT).show();
95             }
96         });
97     }
98 }

转载于:https://www.cnblogs.com/yoyohong/p/7056727.html

Android流式布局控件相关推荐

  1. FlexboxLayout全攻略(Google官方灵活实现流式布局控件)

    一.FlexboxLayout是什么 FlexboxLayout是Google开源的一个强大的控件,直接继承ViewGroup,效果类似于加强版的LinearLayout,但与LinearLayout ...

  2. FlexboxLayout使用(Google官方实现流式布局控件)

    一.FlexboxLayout是什么 FlexboxLayout是Google开源的一个强大的控件,直接继承ViewGroup,效果类似于加强版的LinearLayout,但与LinearLayout ...

  3. Kotlin 第一弹:自定义 ViewGroup 实现流式标签控件

    古人学问无遗力, 少壮工夫老始成.纸上得来终觉浅, 绝知此事要躬行. – 陆游 <冬夜读书示子聿> 上周 Google I/O 大会的召开,宣布了 Kotlin 语言正式成为了官方开发语言 ...

  4. android分组流式布局,Android 流式布局实现

    概述 本文主要分享Android流式布局实现,实现效果如下: 在实现之前先来看一下View的生命周期,如下图: 流式布局属于自定义ViewGroup,重点关注onMeasure与onLayout方法 ...

  5. Android 流式布局

    Android 流式布局 首先目标 最近Android流式布局很火爆,首先我们可以把这一标签页的整体看成一个容器,然后容器内有许多小控件(TextView,Button,ImageView等),再来这 ...

  6. 那些年我们熬夜打造一可收缩流式标签控件

    一.前言 时间匆匆,一眨眼来厦门已经一个多月了.似乎已经适应了这边的生活,喜欢这边的风,温和而舒适,还有淡淡海的味道 ... 还在再次跟大家致个歉意,博客的更新又延期了.新的环境,新的工作加上项目大改 ...

  7. android 流失布局,GitHub - hongyangAndroid/FlowLayout: [不再维护]Android流式布局,支持单选、多选等,适合用于产品标签等。...

    FlowLayout Android流式布局,支持单选.多选等,适合用于产品标签等. ##特色 以setAdapter形式注入数据 直接设置selector为background即可完成标签选则的切换 ...

  8. Android流式布局FlowLayout,一款针对Tag的布局

    交流群 : 668524118 本群主要用于编程技术 ,及创意作品 ,思维架构的交流 ,欢迎喜欢创新 ,热爱生活的朋友加入 ! 前言 flow layout, 流式布局, 这个概念在移动端或者前端开发 ...

  9. Android 图片网格布局控件

    Android 图片网格布局控件 项目地址:MultiPictureView MultiPictureView是一个可以将多张图片以网格的方式显示的View,通过简单的接口实现烦人的布局,从此解放你的 ...

  10. android 自定义flowlayout,Android 流式布局FlowLayout 实现关键字标签

    FlowLayout Android 流式布局FlowLayout 实现关键字标签 效果图 使用方法 在项目根目录的build.gradle文件中加入如下代码 maven { url "ht ...

最新文章

  1. SyntaxError: invalid syntax的问题原因和解决办法
  2. linux c 解析生成json(jansson安装和使用)
  3. swift项目实战FoodPin目录
  4. 黑马程序员_Java面向对象_包
  5. 第四周实践项目5 猴子选大王(循环链表)
  6. Fatal error compiling: 无效的目标发行版: 3.1
  7. 微软全球副总裁给你发了一张Connect 2016专属邀请卡:信仰再充值!Connect 2016技术大会在线直播!
  8. java文件选择器_java中文件选择器JFileChooser的用法
  9. Python的主要功能是什么?
  10. arm-linux-gcc 没有那个文件或目录
  11. 分区字段不在SQL过滤中,悲剧
  12. 2021年中国车轮电机市场趋势报告、技术动态创新及2027年市场预测
  13. Swift学习:字符串和字符(Strings and Characters)
  14. numpy——flat与flatten
  15. php中文九九乘法表,PHP输出九九乘法表代码实例
  16. Kindle fire 刷机
  17. 软件工程(需求分析)
  18. Beetl页面模板文档
  19. 十个接私活赚外快的网站,你有技术就有钱
  20. 360插件化方案RePlugin学习笔记-外置插件

热门文章

  1. 字符串的常用方法和常用类
  2. ios怎么更新测试软件,苹果iOS13 beta3测试版升级教程 iOS13 beta3更新方法
  3. python爬虫之ajax请求爬取豆瓣电影数据
  4. 逻辑学是计算机 创始人,逻辑学的创始人:亚里士多德
  5. Python的Profile概述
  6. 深蓝学院-视觉SLAM十四讲-第一章作业
  7. HTML+CSS静态页面网页设计作业——甜品奶茶店(19页) HTML5网页设计成品_学生DW静态网页设计_web课程设计网页制作
  8. AdSense后台添加美国税务信息W-8BEN纳税表秒过的详细操作图文教程
  9. Python——数学运算函数
  10. 算法篇-union-find并查集