Android流式布局控件
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流式布局控件相关推荐
- FlexboxLayout全攻略(Google官方灵活实现流式布局控件)
一.FlexboxLayout是什么 FlexboxLayout是Google开源的一个强大的控件,直接继承ViewGroup,效果类似于加强版的LinearLayout,但与LinearLayout ...
- FlexboxLayout使用(Google官方实现流式布局控件)
一.FlexboxLayout是什么 FlexboxLayout是Google开源的一个强大的控件,直接继承ViewGroup,效果类似于加强版的LinearLayout,但与LinearLayout ...
- Kotlin 第一弹:自定义 ViewGroup 实现流式标签控件
古人学问无遗力, 少壮工夫老始成.纸上得来终觉浅, 绝知此事要躬行. – 陆游 <冬夜读书示子聿> 上周 Google I/O 大会的召开,宣布了 Kotlin 语言正式成为了官方开发语言 ...
- android分组流式布局,Android 流式布局实现
概述 本文主要分享Android流式布局实现,实现效果如下: 在实现之前先来看一下View的生命周期,如下图: 流式布局属于自定义ViewGroup,重点关注onMeasure与onLayout方法 ...
- Android 流式布局
Android 流式布局 首先目标 最近Android流式布局很火爆,首先我们可以把这一标签页的整体看成一个容器,然后容器内有许多小控件(TextView,Button,ImageView等),再来这 ...
- 那些年我们熬夜打造一可收缩流式标签控件
一.前言 时间匆匆,一眨眼来厦门已经一个多月了.似乎已经适应了这边的生活,喜欢这边的风,温和而舒适,还有淡淡海的味道 ... 还在再次跟大家致个歉意,博客的更新又延期了.新的环境,新的工作加上项目大改 ...
- android 流失布局,GitHub - hongyangAndroid/FlowLayout: [不再维护]Android流式布局,支持单选、多选等,适合用于产品标签等。...
FlowLayout Android流式布局,支持单选.多选等,适合用于产品标签等. ##特色 以setAdapter形式注入数据 直接设置selector为background即可完成标签选则的切换 ...
- Android流式布局FlowLayout,一款针对Tag的布局
交流群 : 668524118 本群主要用于编程技术 ,及创意作品 ,思维架构的交流 ,欢迎喜欢创新 ,热爱生活的朋友加入 ! 前言 flow layout, 流式布局, 这个概念在移动端或者前端开发 ...
- Android 图片网格布局控件
Android 图片网格布局控件 项目地址:MultiPictureView MultiPictureView是一个可以将多张图片以网格的方式显示的View,通过简单的接口实现烦人的布局,从此解放你的 ...
- android 自定义flowlayout,Android 流式布局FlowLayout 实现关键字标签
FlowLayout Android 流式布局FlowLayout 实现关键字标签 效果图 使用方法 在项目根目录的build.gradle文件中加入如下代码 maven { url "ht ...
最新文章
- SyntaxError: invalid syntax的问题原因和解决办法
- linux c 解析生成json(jansson安装和使用)
- swift项目实战FoodPin目录
- 黑马程序员_Java面向对象_包
- 第四周实践项目5 猴子选大王(循环链表)
- Fatal error compiling: 无效的目标发行版: 3.1
- 微软全球副总裁给你发了一张Connect 2016专属邀请卡:信仰再充值!Connect 2016技术大会在线直播!
- java文件选择器_java中文件选择器JFileChooser的用法
- Python的主要功能是什么?
- arm-linux-gcc 没有那个文件或目录
- 分区字段不在SQL过滤中,悲剧
- 2021年中国车轮电机市场趋势报告、技术动态创新及2027年市场预测
- Swift学习:字符串和字符(Strings and Characters)
- numpy——flat与flatten
- php中文九九乘法表,PHP输出九九乘法表代码实例
- Kindle fire 刷机
- 软件工程(需求分析)
- Beetl页面模板文档
- 十个接私活赚外快的网站,你有技术就有钱
- 360插件化方案RePlugin学习笔记-外置插件
热门文章
- 字符串的常用方法和常用类
- ios怎么更新测试软件,苹果iOS13 beta3测试版升级教程 iOS13 beta3更新方法
- python爬虫之ajax请求爬取豆瓣电影数据
- 逻辑学是计算机 创始人,逻辑学的创始人:亚里士多德
- Python的Profile概述
- 深蓝学院-视觉SLAM十四讲-第一章作业
- HTML+CSS静态页面网页设计作业——甜品奶茶店(19页) HTML5网页设计成品_学生DW静态网页设计_web课程设计网页制作
- AdSense后台添加美国税务信息W-8BEN纳税表秒过的详细操作图文教程
- Python——数学运算函数
- 算法篇-union-find并查集