SingleLine 模式的标签云效果,仿知乎问题话题列表

最近因为项目需要,实现了仿知乎话题列表的singleline标签云效果,而因为项目紧张,并没有参考第三方的实现,并且发现效果也还不错。

我们先来看知乎的效果:


首先,我们需要创建一个viewgroup类作为容器,(我这里用Linerlayout来实现)来包含这些需要显示的标签。

在布局文件中定义这个viewgroup类:

<LinearLayout
        android:id="@+id/ll_more_tag"
        android:layout_width="match_parent"
        android:layout_height="48dp"
        android:gravity="center_vertical"
        android:orientation="horizontal" />

标签的布局代码

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="wrap_content"
    android:layout_height="24dp"
    android:background="@drawable/shape_tuijian_bg_default">


    <TextView
        android:id="@+id/tv_tag_name"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginLeft="16dp"
        android:layout_marginRight="16dp"
        android:singleLine="true"
        android:text=""
        android:gravity="center"
        android:textSize="12sp" />
</RelativeLayout>
标签中shape资源代码

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">

    <!-- 圆角 -->
    <corners
        android:bottomLeftRadius="13dp"
        android:bottomRightRadius="13dp"
        android:radius="8dp"
        android:topLeftRadius="13dp"
        android:topRightRadius="13dp" />


    <!-- 填充 -->
    <solid android:color="#ffffff" />
    <!-- 填充的颜色 -->
    <stroke
        android:width="0.5dp"
        android:color="#c5c5c5" />
</shape>


在java代码中:

1.实例化这个viewgroup对象,该对象的引用为llMoreTag

2.需要准备,要显示的标签数据,用集合topList表示

3.先根据toplist集合中的数据,将标签view动态添加到容器中(llMoreTag)

 LinearLayout llMoreTag = (LinearLayout) findViewById(R.id.ll_more_tag);
        List<String> topList = new ArrayList<>();
        //...此处添加toplist集合数据
        int margin = 10;//for example
        int height = 24;//for example
        for (int i = 0; i < topList.size(); i++) {
            View viewTag = View.inflate(this, R.layout.team_title_tagtext, null);
            TextView tagName = (TextView) viewTag.findViewById(R.id.tv_tag_name);
            LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(-2, height);
            params.setMargins(0, 0, margin, 0);
            viewTag.setLayoutParams(params);
            tagName.setText(topList.get(i));
            llMoreTag.addView(viewTag);
        }
4.最关键的一步,当容器中已经将标签实现完成之后,有可能显示下了,也有可能没有显示下,这个时候需要去判读是否标签在一行线性布局中是否显示的了,用到一个比较

关键的类:viewTreeObserver

贴代码:

boolean firstCheck = true;
        llMoreTag.getViewTreeObserver().addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() {
            int totalWidth = 0;

            public boolean onPreDraw() {
                try {
                    totalWidth = 0;
                    for (int i = 0; i < llMoreTag.getChildCount(); i++) {
                        View child = llMoreTag.getChildAt(i);
                        totalWidth = totalWidth + child.getMeasuredWidth() + margin;
                    }
                    if (totalWidth > limitWidth) {
                        if (!firstCheck && llMoreTag.getChildCount() > 0) {
                            llMoreTag.removeViewAt(llMoreTag.getChildCount() - 1);
                        }
                        firstCheck = false;
                        if (llMoreTag.getChildCount() > 0) {
                            View lastChild = llMoreTag.getChildAt(llMoreTag.getChildCount() - 1);
                            TextView lastTag = (TextView) lastChild.findViewById(R.id.tv_tag_name);
                            lastTag.setText("···");
                        }
                    }
                } catch (Exception e) {

                }
                return true;
            }
        });

这一步的关键的思路是,当发现标签全部显示之后,如果超过一行,需要拿到最后一个标签,把最后一个标签移除掉后,再把最后一个标签变成···

实现效果:

只有三个标签的情况:


多余三个标签又显示不下的情况:


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值