前言
美团的外卖商家,电商商品的特点说明,都由一组标签来说明,标签的要求是:1、不满一行不展示可展开图标;2、超过一行的默认展示一行,显示可展开图标,点击可以展开收起;3、在列表中需要保持之前展开或者折叠的状态
实现
Java代码如下:
public class GoodsTagGroupView extends LinearLayout {
private LinearLayout ll_tags;
private FlexboxLayout flexLayout;
private ImageView iv_toggle;
private boolean isExpand = false;
public List<TagBean> tagBeanList;
private ToggleListener listener;
public GoodsTagGroupView(Context context) {
super(context);
initView(context);
}
public GoodsTagGroupView(Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
initView(context);
}
private void initView(Context context) {
View view = LayoutInflater.from(context).inflate(R.layout.goods_tag_group_view,this,true);
ll_tags = view.findViewById(R.id.ll_tags);
flexLayout = view.findViewById(R.id.flexLayout);
iv_toggle = view.findViewById(R.id.iv_toggle);
}
public void setToggleListener(ToggleListener listener){
this.listener = listener;
}
public void setIsExpand(boolean isExpand){
this.isExpand = isExpand;
}
public void setData(List<TagBean> tagBeanList){
this.tagBeanList = tagBeanList;
flexLayout.removeAllViews();
((LinearLayout.LayoutParams)flexLayout.getLayoutParams()).height = LayoutParams.WRAP_CONTENT;
for(int i=0;i<tagBeanList.size();i++){
TextView tv = new TextView(getContext());
tv.setIncludeFontPadding(false);
tv.setGravity(Gravity.CENTER);
tv.setTextSize(10);
tv.setPadding(4,2,4,2);
FlexboxLayout.LayoutParams flps = new FlexboxLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
flps.topMargin = DisplayUtil.dip2px(getContext(),5);
flps.rightMargin = DisplayUtil.dip2px(getContext(),5);
if(1==tagBeanList.get(i).style){
tv.setTextColor(ContextCompat.getColor(getContext(),R.color.goods_tag_color));
tv.setBackgroundResource(R.drawable.goods_label_tag);
}else if(2==tagBeanList.get(i).style){
tv.setTextColor(ContextCompat.getColor(getContext(),R.color.goods_fresh_tag_color));
tv.setBackgroundResource(R.drawable.goods_green_tag);
}else{
tv.setTextColor(ContextCompat.getColor(getContext(),R.color.goods_tag_color));
tv.setBackgroundResource(R.drawable.goods_red_bg_tag);
}
tv.setText(tagBeanList.get(i).name);
flexLayout.addView(tv,flps);
}
/**
* 展开折叠操作
*/
flexLayout.post(new Runnable() {
@Override
public void run() {
int measuredHeight = flexLayout.getMeasuredHeight();
int itemHeight = flexLayout.getChildAt(0).getMeasuredHeight() + DisplayUtil.dip2px(getContext(),5);
if (measuredHeight > itemHeight){//如果大于这个高度,则显示折叠
iv_toggle.setVisibility(View.VISIBLE);
showExpandView(isExpand,measuredHeight,itemHeight);
ll_tags.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
isExpand = !isExpand;
showExpandView(isExpand,measuredHeight,itemHeight);
if(listener!=null){
listener.onToggleClick(isExpand);//保持状态
}
}
});
}else {//如果小于这个高度,则不显示折叠控件
iv_toggle.setVisibility(View.GONE);
}
}
});
}
private void showExpandView(boolean isExpand,int measuredHeight,int itemHeight){
ViewGroup.LayoutParams params = flexLayout.getLayoutParams();
if(isExpand){
params.height = measuredHeight;
iv_toggle.setImageResource(R.mipmap.bq_shang);
}else{
params.height = itemHeight;
iv_toggle.setImageResource(R.mipmap.bq_xia);
}
//调用requestLayout刷新布局
flexLayout.requestLayout();
}
public interface ToggleListener{
void onToggleClick(boolean isExpand);
}
}
xml文件:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout android:id="@+id/ll_tags"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<com.google.android.flexbox.FlexboxLayout
android:id="@+id/flexLayout"
app:flexWrap="wrap"
android:layout_width="0dp"
android:layout_weight="1"
android:layout_height="wrap_content" />
<ImageView
android:id="@+id/iv_toggle"
android:layout_width="23dp"
android:layout_height="20dp"
android:padding="8dp"
android:visibility="gone"
android:src="@mipmap/bq_xia"/>
</LinearLayout>
setData中先正常添加标签,添加完成,在view.post方法中去获取单个标签的高度(即单行的高度)和整个标签组的高度,二者比较来判断是否是多行,并且通过showExpandView来动态改变展开与收起。如果点击过收起展开,可以给一个接口回调在外层将对应位置以及对应位置item的标签组的展开/收起状态保存下来进行恢复。
但是这种写法有个问题,就是加载列表时有时候会让人感觉闪动了一下,因为先是挨个增加了标签,通过实际高度的判断之后再通过flexLayout.requestLayout();来重新布局的,多行标签时第一次加载会闪一下,暂时没有解决。
网友评论