前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >TagLayout自定义流式布局

TagLayout自定义流式布局

作者头像
饮水思源为名
发布2019-11-21 21:15:31
6410
发布2019-11-21 21:15:31
举报
文章被收录于专栏:Android小菜鸡Android小菜鸡

效果图:

实现思路:

这是一个继承ViewGourp来实现的自定义布局。他的核心只有一个,即当子View的宽度超出自身最大宽度时,自动换行。那么,我们先来看核心代码:

代码语言:javascript
复制
    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);

        measureChildren(widthMeasureSpec, heightMeasureSpec);

        final int count = getChildCount(); // tag的数量
        int left = 0; // 当前的左边距离
        int top = 0; // 当前的上边距离
        int totalHeight = 0; // WRAP_CONTENT时控件总高度
        int totalWidth = 0; // WRAP_CONTENT时控件总宽度

        for (int i = 0; i < count; i++) {
            View child = getChildAt(i);

            LinearLayout.LayoutParams params = (LinearLayout.LayoutParams) child.getLayoutParams();

            if (i == 0) { // 第一行的高度
                totalHeight = params.topMargin + child.getMeasuredHeight() + params.bottomMargin;
            }

            if (left + params.leftMargin + child.getMeasuredWidth() + params.rightMargin > getMeasuredWidth()) { // 换行
                left = 0;
                top += params.topMargin + child.getMeasuredHeight() + params.bottomMargin; // 每个TextView的高度都一样,随便取一个都行
                totalHeight += params.topMargin + child.getMeasuredHeight() + params.bottomMargin;
            }

            children.add(new int[]{left + params.leftMargin, top + params.topMargin, left + params.leftMargin + child.getMeasuredWidth(), top + params.topMargin + child.getMeasuredHeight()});

            left += params.leftMargin + child.getMeasuredWidth() + params.rightMargin;

            if (left > totalWidth) { // 当宽度为WRAP_CONTENT时,取宽度最大的一行
                totalWidth = left;
            }
        }

        int height = 0;
        if (MeasureSpec.getMode(heightMeasureSpec) == MeasureSpec.EXACTLY) {
            height = MeasureSpec.getSize(heightMeasureSpec);
        } else {
            height = totalHeight;
        }

        int width = 0;
        if (MeasureSpec.getMode(widthMeasureSpec) == MeasureSpec.EXACTLY) {
            width = MeasureSpec.getSize(widthMeasureSpec);
        } else {
            width = totalWidth;
        }

        setMeasuredDimension(width, height);
    }

毫无疑问,onMeasure是这个自定义布局的核心,笔者不仅在改方法中实现了测量,同时还会记录子控件的左上右下四个坐标位置信息,存在一个ArrayList<int []> 中。以便在onLayout中直接赋值。

简单的解析一下代码,在子View的循环中,我们首先获取一次子View的高度,而每次换行时,再叠加高度,最终用于Warp-Content时,高度的测量。而宽度则取最宽的一行的值。 设置一个当前的左上点坐标。确定每一个子View的左上点坐标后,通过子View的宽高确定右下点坐标。即完成了对一个子View的测量。

如何使用:

代码语言:javascript
复制
 for (index in list.indices){
            val layout=LayoutInflater.from(context).inflate(R.layout.item_text_card,null)
            val tv=layout.findViewById<TextView>(R.id.tv)
            val params = LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.WRAP_CONTENT)
            params.setMargins(20, 20, 0, 0)
            tv.text=list[index].text
            layout.setOnClickListener {
                if(listener!=null) listener!!.onItemClick(list[index],index)
                dismiss()
            }
            tags.addView(layout,params)
        }
代码语言:javascript
复制
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical" android:layout_width="match_parent"
    android:background="#F0EFEF"
    android:layout_height="450dp">
    <ImageView
        android:id="@+id/ivCancel"
        android:layout_gravity="right"
        android:padding="15dp"
        android:src="@mipmap/icon_schedule_close"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"/>
    <ScrollView
        android:layout_width="match_parent"
        android:layout_height="match_parent">
        <com.hjl.artisan.app.TagLayout
            android:id="@+id/tags"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"/>

    </ScrollView>

</LinearLayout>

源码:

wusyLibrary://wusylibrary/src/main/java/com/wusy/wusylibrary/view/TagLayout.java

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 效果图:
  • 实现思路:
  • 如何使用:
  • 源码:
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档