热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

Android瀑布流控件的实现

**Android瀑布流控件的实现**—————————————————–(java架构师全套教程,共760G,让你从零到架构师,每月轻松拿3万&#

**

Android 瀑布流控件的实现

**
—————————————————–
(java 架构师全套教程,共760G, 让你从零到架构师,每月轻松拿3万)
请先拍 购买地址, 下载请用百度盘
目录如下:
01.高级架构师四十二个阶段高
02.Java高级系统培训架构课程148课时
03.Java高级互联网架构师课程
04.Java互联网架构Netty、Nio、Mina等-视频教程
05.Java高级架构设计2016整理-视频教程
06.架构师基础、高级片
07.Java架构师必修linux运维系列课程
08.Java高级系统培训架构课程116课时
(送:hadoop系列教程,java设计模式与数据结构, Spring Cloud微服务, SpringBoot入门)
01高级架构师四十二个阶段高内容:
01高级架构师四十二个阶段高内容:
这里写图片描述
这里写图片描述
—————————————————–

public class FlowLayout extends ViewGroup {/**行里子view之间的行距离*/public int mHorizontolSpace &#61; Util.getDimen(R.dimen.top_padding);/**行里子view之间的垂直距离*/public int mVerticalSpace &#61; Util.getDimen(R.dimen.top_padding);/**创建行的集合*/private List mLines &#61; new ArrayList();/**当前行*/private Line mCurrentLine;/**当前行使用的宽度*/private int mCurrentUseWidth &#61; 0;/**父容器的宽高*/private int parentWidthSize;private int parentHeightSize;public FlowLayout(Context context, AttributeSet attrs, int defStyleAttr) {super(context, attrs, defStyleAttr);}public FlowLayout(Context context, AttributeSet attrs) {super(context, attrs);}public FlowLayout(Context context) {super(context);}&#64;Overrideprotected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {//0.先清空行集合里的数据clear();//1.得到父viewGroup的模式与大小int parentWidthMode &#61; MeasureSpec.getMode(widthMeasureSpec);//parentWidthSize &#61; MeasureSpec.getSize(widthMeasureSpec) - getPaddingLeft() - getPaddingRight();int parentHeightMode &#61; MeasureSpec.getMode(heightMeasureSpec);parentHeightSize &#61; MeasureSpec.getSize(heightMeasureSpec) - getPaddingBottom() - getPaddingTop();/* 每个子view都是包裹内容* layout.addView(mTextView, new LinearLayout.LayoutParams(LayoutParams.WRAP_CONTENT* 得到每个孩子的测量规则*///2.得到每个孩子的模式int childWidthMode &#61; parentWidthMode &#61;&#61; MeasureSpec.EXACTLY ? MeasureSpec.EXACTLY : parentWidthMode;int childHeightMode &#61; parentHeightMode &#61;&#61; MeasureSpec.EXACTLY ? MeasureSpec.EXACTLY : parentHeightMode;//3.根据模式得到子控件的大小int childWidthMeasureSpec &#61; MeasureSpec.makeMeasureSpec(childWidthMode, parentWidthSize);int childHeightMeasureSpec &#61; MeasureSpec.makeMeasureSpec(childHeightMode, parentHeightSize);//得到子view的个数int count &#61; getChildCount();//创建新的行mCurrentLine &#61; new Line();for (int i &#61; 0; i //4.测量每个孩子childView.measure(childWidthMeasureSpec, childHeightMeasureSpec);//5.得到测量后的孩子的宽高int childMeasureWidth &#61; MeasureSpec.getSize(childWidthMeasureSpec);//int childMeasureHeight &#61; MeasureSpec.getSize(childHeightMeasureSpec);//6.得到此行使用的宽度mCurrentUseWidth &#43;&#61; childMeasureWidth;//7.判断此行的宽度是否大于父控件的宽度&#xff0c;如果大于则换行if (mCurrentUseWidth > parentWidthSize) {//8.如果当前的子view的宽度大于富容器的宽度&#xff0c;强行把这个view添加的集合里if (mCurrentLine.getChildCount()<1) {mLines.add(mCurrentLine); }//9.换行newLine();}else {//8.把当前子view添加到行里mCurrentLine.addChild(childView);//9.添加间隔mCurrentUseWidth &#43;&#61; mHorizontolSpace;if (mCurrentUseWidth > parentWidthSize) {//10.换行newLine();}}}//11.如果集合里没有添加当前行&#xff0c;则把当前添加到集合if (!mLines.contains(mCurrentLine)) {mLines.add(mCurrentLine);}//12.设置富容器的总宽高int parentWidth &#61; parentWidthSize &#43; getPaddingLeft() &#43; getPaddingRight();int parentHeight &#61; (mLines.size()-1) * mVerticalSpace &#43; getPaddingBottom() &#43; getPaddingTop();for(Line line : mLines){//得到所以line的高度parentHeight &#43;&#61; line.getHeight();}//13.resolveSize表示哪个高度合适&#xff0c;就用哪个setMeasuredDimension(parentWidth, resolveSize(parentHeightSize, parentHeight));/*setMeasuredDimension(getDefaultSize(getSuggestedMinimumWidth(), widthMeasureSpec),getDefaultSize(getSuggestedMinimumHeight(), heightMeasureSpec));*/}/*** 换行*/private void newLine() {//a.先把当前的行添加到集合mLines.add(mCurrentLine);//b.创建新的一行mCurrentLine &#61; new Line();//c.新行里的使用的行必须设置为0mCurrentUseWidth &#61; 0;}public void clear() {mLines.clear();mCurrentLine &#61; null;mCurrentUseWidth &#61; 0;}&#64;Overrideprotected void onLayout(boolean changed, int l, int t, int r, int b) {//15.得到每个line孩子的左上角的坐标int left &#61; l &#43; getPaddingLeft();int top &#61; t &#43; getPaddingTop();//现在容器里只有line是子孩子for (int i &#61; 0; i //16.把分配位置给line去处理line.layout(left, top);//17.设置第一行后的其它行的top数值top &#43;&#61; line.getHeight() &#43; mVerticalSpace;}}/*** 行类&#xff0c;用来封装一行的view*/private class Line{/**当前行的宽度*/private int mWidth &#61; 0;/**当前行的高度*/private int mHeight &#61; 0;/**每个孩子得到的剩余空间*/int mChildPdding &#61; 0;private List children &#61; new ArrayList();public void addChild(View childView) {children.add(childView);//取得之view里最高的高度if (childView.getMeasuredHeight() > mHeight) {mHeight &#61; childView.getMeasuredHeight();}//18.得到行宽度mWidth &#43;&#61; childView.getMeasuredWidth();}/*** 定位每个line在富容器里的额位置* &#64;param left* &#64;param top*/public void layout(int left, int top) {//18.得到行宽度mWidth &#43;&#61; mHorizontolSpace * (children.size() -1);//19.得到剩余的宽度大小//int padding &#61; getMeasuredWidth() - mWidth;int padding &#61; parentWidthSize - mWidth;if (padding > 0) {mChildPdding &#61; padding / children.size();}// getWidth()view显示的时候大小,如果view没显示,这个值就为0,步包括隐藏的部分, getMeasuredWidth()控件实际大小,包括隐藏的部分//一般来说 getMeasuredWidth() > getWidth();for (int i &#61; 0; i //第一种&#xff1a;有间隔的flowint bottom &#61; child.getMeasuredHeight() &#43; top;//20.把剩余的空间分配给每个viewint right &#61; child.getMeasuredWidth() &#43; left &#43; mChildPdding;//第二种&#xff1a;无间隔的flow
// int bottom &#61; getMeasuredHeight() &#43; top;
// int right &#61; getMeasuredWidth() &#43; left;//第一个child的位置child.layout(left, top, right, bottom);//第二个及后面child的rightright &#43;&#61; child.getMeasuredWidth() &#43; mHorizontolSpace &#43; mChildPdding;}}/*** 得到子view的大小* &#64;return*/public int getChildCount() {if (children !&#61; null) {return children.size();}return 0;}public int getHeight() {return mHeight;}}}

使用方法&#xff1a;

public class TopFragment extends Fragment{&#64;Overridepublic View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {ScrollView scrollView &#61; new ScrollView(getActivity());FlowLayout layout &#61; new FlowLayout(getActivity());layout.setBackgroundDrawable(Util.getDrawable(R.drawable.list_item_bg));int padding &#61; Util.getDimen(R.dimen.top_padding);layout.setPadding(padding, padding, padding, padding);GradientDrawable pressDrawable &#61; DrawableUtil.createDrawable(0xffcecece);for (int i &#61; 0; i new TextView(getActivity());mTextView.setText(mDatas.get(i));GradientDrawable randomDrawable &#61; DrawableUtil.createRandomDrawable();StateListDrawable stateListDrawable &#61; DrawableUtil.createStateDrawable(pressDrawable, randomDrawable);mTextView.setBackgroundDrawable(stateListDrawable);mTextView.setTextColor(Color.WHITE);int left &#61; Util.px2dip(7);int top &#61; Util.px2dip(4);int right &#61; Util.px2dip(7);int bottom &#61; Util.px2dip(4);mTextView.setPadding(left, top, right, bottom);mTextView.setTag(mDatas.get(i));mTextView.setOnClickListener(this);layout.addView(mTextView, new LinearLayout.LayoutParams(LayoutParams.WRAP_CONTENT, - 2));}scrollView.addView(layout);}return scrollView;
}

工具类:

public class DrawableUtil {/*** 创建随机背景的drawable* &#64;return*/public static GradientDrawable createRandomDrawable(){GradientDrawable drawable &#61; new GradientDrawable();drawable.setCornerRadius(Util.px2dip(5));Random random &#61; new Random();int red &#61; random.nextInt(200) &#43; 20;int green &#61; random.nextInt(200) &#43; 20;int blue &#61; random.nextInt(200) &#43; 20;int color &#61; Color.rgb(red, green, blue);drawable.setColor(color);return drawable;}/*** 创建带有背景的drawable* &#64;return*/public static GradientDrawable createDrawable(int color){GradientDrawable drawable &#61; new GradientDrawable();drawable.setCornerRadius(Util.px2dip(5));drawable.setColor(color);return drawable;}/*** 状态选择器* &#64;param press* &#64;param normal* &#64;return*/public static StateListDrawable createStateDrawable(Drawable press, Drawable normal){StateListDrawable drawable &#61; new StateListDrawable();//按下drawable.addState(new int[]{android.R.attr.state_pressed}, press);//正常drawable.addState(new int[]{}, normal);return drawable;}
}


推荐阅读
  • 从无到有,构建个人专属的操作系统解决方案
    操作系统(OS)被誉为程序员的三大浪漫之一,常被比喻为计算机的灵魂、大脑、内核和基石,其重要性不言而喻。本文将详细介绍如何从零开始构建个人专属的操作系统解决方案,涵盖从需求分析到系统设计、开发与测试的全过程,帮助读者深入理解操作系统的本质与实现方法。 ... [详细]
  • Python 数据可视化实战指南
    本文详细介绍如何使用 Python 进行数据可视化,涵盖从环境搭建到具体实例的全过程。 ... [详细]
  • Ansible:自动化运维工具详解
    Ansible 是一款新兴的自动化运维工具,基于 Python 开发,集成了多种运维工具(如 Puppet、CFEngine、Chef、Func 和 Fabric)的优点,实现了批量系统配置、程序部署和命令执行等功能。本文将详细介绍 Ansible 的架构、特性和优势。 ... [详细]
  • Juval Löwy主张,每个类都应被视为服务,这并非是为了让服务无处不在,而是因为微服务是经过深思熟虑后系统分解的自然结果。在他的设计和构建的系统中,这种理念有助于提高模块化、可维护性和扩展性。通过将每个类视为独立的服务,系统能够更好地应对复杂性,实现更灵活的部署和更高的性能。 ... [详细]
  • MySQL 8.0 MGR 自动化部署与配置:DBA 和开源工具的高效解决方案
    MySQL 8.0 MGR 自动化部署与配置:DBA 和开源工具的高效解决方案 ... [详细]
  • 汽车电子架构与CAN网络基础解析——鉴源实验室专业解读 ... [详细]
  • 本文探讨了使用Python进行微服务架构设计的合理性和适用性。首先,介绍了微服务的基本概念及其在现代软件开发中的重要性。接着,通过具体的业务场景,详细分析了Python在微服务架构设计中的优势和挑战。文章还讨论了在实际应用中可能遇到的问题,并提出了相应的解决方案。希望本文能够为从事Python微服务开发的技术人员提供有价值的参考和指导。 ... [详细]
  • Docker入门指南:初探容器化技术
    Docker入门指南:初探容器化技术摘要:Docker 是一个使用 Go 语言开发的开源容器平台,旨在实现应用程序的构建、分发和运行的标准化。通过将应用及其依赖打包成轻量级的容器,Docker 能够确保应用在任何环境中都能一致地运行,从而提高开发和部署的效率。本文将详细介绍 Docker 的基本概念、核心功能以及如何快速上手使用这一强大的容器化工具。 ... [详细]
  • 解读中台架构:微服务与分布式技术的区别及应用
    中心化与去中心化是长期讨论的话题。中心化架构的优势在于部署和维护相对简单,尤其在服务负载较为稳定的情况下,能够提供高效稳定的性能。然而,随着业务规模的扩大和技术需求的多样化,中心化架构的局限性逐渐显现,如扩展性和故障恢复能力较差。相比之下,微服务和分布式技术通过解耦系统组件,提高了系统的灵活性和可扩展性,更适合处理复杂多变的业务场景。本文将深入探讨中台架构中微服务与分布式技术的区别及其应用场景,帮助读者更好地理解和选择适合自身业务的技术方案。 ... [详细]
  • 技术日志:Ansible的安装及模块管理详解 ... [详细]
  • 如何在Oracle ASM_Diskgroup中重命名现有磁盘
    如何在Oracle ASM_Diskgroup中重命名现有磁盘 ... [详细]
  • 修复一个 Bug 竟耗时两天?真的有那么复杂吗?
    修复一个 Bug 竟然耗费了两天时间?这背后究竟隐藏着怎样的复杂性?本文将深入探讨这个看似简单的 Bug 为何会如此棘手,从代码层面剖析问题根源,并分享解决过程中遇到的技术挑战和心得。 ... [详细]
  • PJSIP 编译与开发指南:深入解析 PJSIP 库的应用与优化
    PJSIP 编译与开发指南:深入解析 PJSIP 库的应用与优化 ... [详细]
  • 腾讯与阅文集团在技术领域展开合作,共同推进微服务框架Tars的发展。此次合作中,Tars新增了对PHP语言的支持,不仅强化了Tars-PHP作为客户端的功能,还显著提升了其在服务端的应用能力。这一改进旨在满足不同业务场景下的多样化需求,为开发者提供更加灵活和高效的技术解决方案。 ... [详细]
  • 阿里巴巴Java后端开发面试:TCP、Netty、HashMap、并发锁与红黑树深度解析 ... [详细]
author-avatar
范婷柏
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有