您的位置:首页 > 其它

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

2015-08-31 14:47 120 查看
最近因为项目需要,实现了仿知乎话题列表的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;
}
});


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

实现效果:

只有三个标签的情况:



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

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: