热门标签 | 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;}
}


推荐阅读
  • 一次上线事故,30岁+的程序员踩坑经验之谈
    本文主要介绍了一位30岁+的程序员在一次上线事故中踩坑的经验之谈。文章提到了在双十一活动期间,作为一个在线医疗项目,他们进行了优惠折扣活动的升级改造。然而,在上线前的最后一天,由于大量数据请求,导致部分接口出现问题。作者通过部署两台opentsdb来解决问题,但读数据的opentsdb仍然经常假死。作者只能查询最近24小时的数据。这次事故给他带来了很多教训和经验。 ... [详细]
  • TiDB | TiDB在5A级物流企业核心系统的应用与实践
    TiDB在5A级物流企业核心系统的应用与实践前言一、业务背景科捷物流概况神州金库简介二、现状与挑战神州金库现有技术体系业务挑战应对方案三、TiDB解决方案测试迁移收益问题四、说在最 ... [详细]
  • java程序员_9大行为导致Java程序员薪资过低, 你有几个?
    Java程序员薪水有高有低,有的人一个月可能拿30K、50K,有的人可能只有2K、3K。同样有五年工作 ... [详细]
  • flowable工作流 流程变量_信也科技工作流平台的技术实践
    1背景随着公司业务发展及内部业务流程诉求的增长,目前信息化系统不能够很好满足期望,主要体现如下:目前OA流程引擎无法满足企业特定业务流程需求,且移动端体 ... [详细]
  • 本文介绍了一款名为TimeSelector的Android日期时间选择器,采用了Material Design风格,可以在Android Studio中通过gradle添加依赖来使用,也可以在Eclipse中下载源码使用。文章详细介绍了TimeSelector的构造方法和参数说明,以及如何使用回调函数来处理选取时间后的操作。同时还提供了示例代码和可选的起始时间和结束时间设置。 ... [详细]
  • Sleuth+zipkin链路追踪SpringCloud微服务的解决方案
    在庞大的微服务群中,随着业务扩展,微服务个数增多,系统调用链路复杂化。Sleuth+zipkin是解决SpringCloud微服务定位和追踪的方案。通过TraceId将不同服务调用的日志串联起来,实现请求链路跟踪。通过Feign调用和Request传递TraceId,将整个调用链路的服务日志归组合并,提供定位和追踪的功能。 ... [详细]
  • 提供:ZStack云计算原创2016-12-26张鑫讲师介绍张鑫ZStack总架构师、联合创始人《系统虚拟化》主要作者,曾任职Intel开源软件技术中心 ... [详细]
  • SOA架构理解理解SOA架构,了解ESB概念,明白SOA与微服务的区别和联系,了解SOA与热门技术的结合与应用。1、面向服务的架构SOASOA(ServiceOrien ... [详细]
  • [我们是谁?] ... [详细]
  • 博客_2018年博客总结
    本文由编程笔记#小编为大家整理,主要介绍了2018年博客总结相关的知识,希望对你有一定的参考价值。前言     ... [详细]
  • 云原生SRE
    序言年底了,没有分手的朋友的赶紧分了,所谓新年新气象,年年不重样。去留无意,望看风卷残云。。。运维不会消失,但 ... [详细]
  • 详解Netty Zero Copy机制
    NettyZeroCopy的巧妙设计让Netty从众多高性 ... [详细]
  • 微服务下的几个难点问题及常见的解决方案
    原文链接:https:cloud.tencent.comdevelopernews1362051背景介绍1.1幂等性定义数学定义在数学里,幂等有 ... [详细]
  • 前言最近一段时间在整公司项目里一个功能的优化,用到了多线程处理。期间也是踩了不少的坑,在这里想说下我遇到的问题和注意事项。以及怎样知道启动的那些多线程都 ... [详细]
  • 阿里首席架构师科普RPC框架
    RPC概念及分类RPC全称为RemoteProcedureCall,翻译过来为“远程过程调用”。目前,主流的平台中都支持各种远程调用技术,以满足分布式系统架构中不同的系统之间的远程 ... [详细]
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社区 版权所有