最近项目中在做热搜和历史搜索记录,开始是将横屏平均分成三份进行显示,后来需求说像个豆腐块,太难看了,要求是按着搜索输入的字的多少进行显示,就想天猫APP历史搜索那样的效果进行显示,其实这样的效果不用我们去写,可以在网上找一些想过资料,我在github上找了个,不能用,我一直怀疑是我这边使用方法出错了,但是检查了几遍也没找到错误,所以我又找了个,成功!!所以是控件出现问题。

下面是正确的控件

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);}/**
     * 父容器生成 子view 的布局LayoutParams;
     * 一句话道出LayoutParams的本质:LayoutParams是Layout提供给其中的Children使用的。
     * 如果要自定义ViewGroup支持子控件的layout_margin参数,则自定义的ViewGroup类必须重载generateLayoutParams()函数,
     * 并且在该函数中返回一个ViewGroup.MarginLayoutParams派生类对象,这样才能使用margin参数。
     */
    @Override
    protected LayoutParams generateLayoutParams(LayoutParams p){return new MarginLayoutParams(p);}@Override
    public LayoutParams generateLayoutParams(AttributeSet attrs){return new MarginLayoutParams(getContext(), attrs);}@Override
    protected LayoutParams generateDefaultLayoutParams(){return new MarginLayoutParams(LayoutParams.MATCH_PARENT,LayoutParams.MATCH_PARENT);}@Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {super.onMeasure(widthMeasureSpec, heightMeasureSpec);int measureWidth = MeasureSpec.getSize(widthMeasureSpec);int measureHeight = MeasureSpec.getSize(heightMeasureSpec);int measureWidthMode = MeasureSpec.getMode(widthMeasureSpec);int measureHeightMode = MeasureSpec.getMode(heightMeasureSpec);int lineWidth = 0;int lineHeight = 0;int height = 0;int width = 0;int count = getChildCount();for (int i=0;i<count;i++){View child = getChildAt(i);measureChild(child,widthMeasureSpec,heightMeasureSpec);//如果忘记重写generateLayoutParams,则hild.getLayoutParams()将不是MarginLayoutParams的实例
            //在强制转换时就会出错,此时我们把左右间距设置为0,但由于在计算布局宽高时没有加上间距值,就是计算出的宽高要比实际小,所以是onLayout时就会出错
            MarginLayoutParams lp = null;if (child.getLayoutParams() instanceof MarginLayoutParams) {lp = (MarginLayoutParams) child.getLayoutParams();}else{lp = new MarginLayoutParams(0,0);}int childWidth = child.getMeasuredWidth() + lp.leftMargin +lp.rightMargin;int childHeight = child.getMeasuredHeight() + lp.topMargin + lp.bottomMargin;if (lineWidth + childWidth > measureWidth){//需要换行
                width = Math.max(lineWidth,width);height += lineHeight;//因为由于盛不下当前控件,而将此控件调到下一行,所以将此控件的高度和宽度初始化给lineHeight、lineWidth
                lineHeight = childHeight;lineWidth = childWidth;}else{// 否则累加值lineWidth,lineHeight取最大高度
                lineHeight = Math.max(lineHeight,childHeight);lineWidth += childWidth;}//最后一行是不会超出width范围的,所以要单独处理
            if (i == count -1){height += lineHeight;width = Math.max(width,lineWidth);}}//当属性是MeasureSpec.EXACTLY时,那么它的高度就是确定的,
        // 只有当是wrap_content时,根据内部控件的大小来确定它的大小时,大小是不确定的,属性是AT_MOST,此时,就需要我们自己计算它的应当的大小,并设置进去
        setMeasuredDimension((measureWidthMode == MeasureSpec.EXACTLY) ? measureWidth: width, (measureHeightMode == MeasureSpec.EXACTLY) ? measureHeight: height);}@Override
    protected void onLayout(boolean changed, int l, int t, int r, int b) {int count = getChildCount();int lineWidth = 0;int lineHeight = 0;int top=0,left=0;for (int i=0; i<count;i++){View child = getChildAt(i);MarginLayoutParams lp = (MarginLayoutParams) child.getLayoutParams();int childWidth = child.getMeasuredWidth()+lp.leftMargin+lp.rightMargin;int childHeight = child.getMeasuredHeight()+lp.topMargin+lp.bottomMargin;if (childWidth + lineWidth >getMeasuredWidth()){//如果换行,当前控件将跑到下一行,从最左边开始,所以left就是0,而top则需要加上上一行的行高,才是这个控件的top点;
                top += lineHeight;left = 0;//同样,重新初始化lineHeight和lineWidth
                lineHeight = childHeight;lineWidth = childWidth;}else{lineHeight = Math.max(lineHeight,childHeight);lineWidth += childWidth;}//计算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置为下一子控件的起始点
            left+=childWidth;}}}

使用和普通的自定义控件一样

<com.FlowLayout
    android:id="@+id/ll_history"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"

    ><TextView
            android:id="@+id/tv_text1"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_margin="4dp"
            android:background="@drawable/hotsearch_bg"
            android:gravity="center"
            android:textSize="14sp"


            /><TextView
            android:id="@+id/tv_text2"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_margin="4dp"
            android:background="@drawable/hotsearch_bg"
            android:gravity="center"
            android:textSize="14sp"
            />
</com.FlowLayout>

有需要的时候可以直接拿来用

流式布局实现热搜和历史搜索相关推荐

  1. android 搜索历史流布局,FlowLayout流式布局实现搜索清空历史记录

    本文实例为大家分享了FlowLayout实现搜索清空历史记录的具体代码,供大家参考,具体内容如下 效果图:点击搜索框将搜索的历史在流式布局中展示出来,清空历史记录就会将历史清空,每次搜索后都存入sp中 ...

  2. 流式布局清空历史搜索

    依赖: 1.添加依赖 ①.在项目的 build.gradle 文件中添加 allprojects {repositories {...maven { url 'https://jitpack.io' ...

  3. android搜索热词(热门标签)流式布局的实现

    先看下效果图 1.流式布局实现 继承ViewGroup,重写onMeasure,onLayout方法.代码如下: package com.example.lin.flowlayoutdemo;impo ...

  4. 自定义 FlowLayout流式布局搜索框 加 GreenDao存取搜索记录,使用RecyclerView展示

    输入框布局的shape <?xml version="1.0" encoding="utf-8"?> <shape xmlns:android ...

  5. html流式布局怎么用,css 流式布局什么意思?

    流式布局,也叫百分比布局,是移动端开发中经常使用的布局方式之一.流式布局在CSS2时代就有,主要是靠百分比进行排版,可以在不同分辨率下显示相同的版式. 流式布局:网页中主要的划分区域的尺寸使用百分数( ...

  6. 移动web现状、viewport视口、二倍图、移动web开发主流方案、布局技术选型(流式布局、flex弹性布局、less+rem+媒体查询布局、混合布局、媒体查询、bootstrap)

    移动端web现状: 移动端常见浏览器:UC浏览器,QQ浏览器,Opera浏览器,百度手机浏览器,360安全浏览器,谷歌浏览器,搜狗手机浏览器,猎豹浏览器及杂牌浏览器.移动端常见的浏览器都是基于webk ...

  7. 仿唯品会/京东/淘宝搜索流式布局的隐藏与展示

    1. 项目需求: 如下,如果没有向下箭头(显示/隐藏剩余搜索词条)的话,采用flexbox-layout+Recycleview+FlexboxLayoutManager 可以实现流式布局. 加了这个 ...

  8. CSS的三大布局方式(流式布局,浮动布局和层布局)

    文章目录 前言 一.标准文档流 二.三种布局方式 1.流式布局 2.浮动布局 (1)字围效果 (2)圣杯布局 3.层布局 定位的分类: (1) 相对定位 position:relative (2) 绝 ...

  9. FlowLayout流式布局实现搜索清空历史记录

    效果图:点击搜索框将搜索的历史在流式布局中展示出来,清空历史记录就会将历史清空,每次搜索后都存入sp中,每次进入页面都先判断sp里是否有值并展示 首先需要导入一个module,下载地址:https:/ ...

最新文章

  1. 解决Inno Setup制作安装包无法创建桌面快捷方式的问题
  2. 【控制】系统典型环节及其拉氏变换并绘制阶跃响应曲线和脉冲响应曲线
  3. 【word2vec】篇三:基于Negative Sampling 的 CBOW 模型和 Skip-gram 模型
  4. Confluent官博:Kafka最牛队列,性能15倍于RabbitMQ!
  5. [渝粤教育] 上海交通大学 制造工艺基础 参考 资料
  6. 深入理解计算机系统 相关课程,深入理解计算机系统
  7. 【人工智能中“预测”的知识点】
  8. mysql查询报错2014_mysql Hibernate 查询时用别名报错
  9. 创建表结构相同的表,表结构相同的表之间复制数据,Oracle 中 insert into XXX select from 的用法...
  10. IP与以太网的包收发操作
  11. PDF Checkpoint for mac(pdf文件批量处理工具)
  12. 行业动态_天才、忽悠与炮灰
  13. linux如何查看vlan信息,dhcp – 通过tcpdump在数据包捕获(Linux)中未显示VLAN标记
  14. sap销售发货的流程_基于SAP系统批量创建销售订单及交货单过账的方法与流程
  15. 无法访问,您可能没有权限使用网络资源的解决
  16. 收藏了8年的PHP优秀资源,都给你整理好了
  17. 10015---MySQL--innodb_flush_log_at_trx_commit参数
  18. 基于微信小程序的毕业设计题目(25)php体育馆场地预约小程序(含开题报告、任务书、中期报告、答辩PPT、论文模板)
  19. nps内网穿透服务器搭建教程(阿里云)-小宇特详解
  20. XPE启动蓝屏或FBA反复重启的问题

热门文章

  1. 网店运营不得当会导致天猫网店降权你知道吗?知米易教你解决
  2. android开发之ExpandableListView的使用,实现类似QQ好友列表
  3. 脑数据有多重要?脑机接口有哪些商业应用?
  4. spark 无法写入hive表Can not create the managed table,该如何解决?
  5. Android 高效现实图片问题
  6. the lenght of int
  7. Ventuz6之模型动画节点[Animation Rig]
  8. samtools + bcftools
  9. 快速搭建自己的跑腿服务平台:开源跑腿系统源码分享
  10. ChatGPT对软件开发和软件产品的价值