LabelFlowLayout(流式标签布局)

总概
1,使用效果
2,使用方法
3,源码介绍
4,参考
5,github地址

1,使用效果
1) 动态增加和减少label数量

2)每行最多3个数 + 中心布局

3)动态修改选中状态

4)设置只选择1个(最少1个,最多1个)【略】
5)设置只选择2个(最少2个,最多2个)【略】
6)设置最少2个,最多4个

7)设置成高亮,全部不可点击【略】
8)TextView背景(check、select、press三个效果同步)【略】

2,使用方法
xml布局(主)
<com.lib.LabelFlowLayout
    android:id="@+id/layout_flow_label_drawable_one"
    android:layout_width="match_parent"
    android:layout_height="wrap_content">
</com.lib.LabelFlowLayout>
子布局(每一个item) 注意:doplicateParentState="true"参数; 否则,子控件状态不会改变
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content">

    <TextView
        android:id="@+id/tv_label"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_margin="5dp"
        android:background="@drawable/label_bg_click"
        android:duplicateParentState="true"
        android:text="text"
        android:textColor="@drawable/label_text_color_click">
    </TextView>
</LinearLayout>

Java
private LabelFlowLayout labelFlowLayoutOne; // 父布局
private LabelAdapter labelAdapterOne; // adapter
// 找到控件,设置adapter
labelFlowLayoutOne = (LabelFlowLayout) view.findViewById(R.id.layout_flow_label_drawable_one);
labelAdapterOne = new DrawableClickAdapter();
labelFlowLayoutOne.setAdapter(labelAdapterOne);
// 通过adapter设置点击事件
labelAdapterOne.setDataList(Arrays.asList(DeleteData.dataTwo));
labelAdapterOne.setOnLabelClickListener(new LabelAdapter.OnLabelClickListener()
{
   @Override
   public boolean onLabelClick(FlowLayout container, View view, Object o, int position)
   {
      return false;
   }
});
labelAdapterOne.setOnLabelSelectListener(new LabelAdapter.OnLabelSelectListener()
{
   @Override
   public void onLabelSelected(Deque selectedDeque)
   {
      getActivity().setTitle("choose:" + selectedDeque.toString());
   }
});

private class DrawableClickAdapter extends LabelAdapter<String>
{
   @Override
   public int getDataSize()
   {
      return super.getDataSize();
   }
   
   @Override
   public View getView(FlowLayout container, String s, int position)
   {
      LinearLayout linearLayout = (LinearLayout) LayoutInflater.from(getContext()).inflate(R.layout.item_label_click, container, false);
      
      TextView tvItem = (TextView) linearLayout.findViewById(R.id.tv_label);
      tvItem.setText(s);
      
      return linearLayout;
   }
}

其他配置:
对控件的自定义:(即:可通过xml配置的参数)
<declare-styleable name="WidgetLabelLayout">
    <attr name="label_max_select" format="integer"></attr> // 最大选择数
    <attr name="label_min_select" format="integer"></attr> // 最小选择数
    <attr name="label_max_count_each_line" format="integer"></attr> // 每行最多个数
    <attr name="label_gravity"> // label的重心
        <enum name="left" value="-1"/>
        <enum name="center" value="0"/>
        <enum name="right" value="1"/>
    </attr>
</declare-styleable>
java配置:
// selected相关
labelAdapterOne.addSelectedPosition(0); // 增加某一项
labelAdapterOne.addAllSelectedPosition(Arrays.asList(0, 1, 2, 3, 4, 5)); // 增加好几项
labelAdapterOne.getSelectedList(); // 获取当前选择项
labelAdapterOne.getSelectedFirst(); // 获取第一个选择的项
labelAdapterOne.getSelectedSize(); // 获取当前选择的个数
labelAdapterOne.removeSelectedPosition(0); // 移除某一个选择项
labelAdapterOne.clearSelectedPosition(); // 移除全部选择项

// data相关
labelAdapterOne.addData("add=3"); // 增加一条数据
labelAdapterOne.addAllDataList(Arrays.asList("add=1", "add=2")); // 增加多条数据
labelAdapterOne.getItem(0); // 依据位置,获取内容
labelAdapterOne.removeData(0); // 依据位置,移除内容
labelAdapterOne.removeData("add=3"); // 依据内容,移除内容
labelAdapterOne.setDataList(Arrays.asList(DeleteData.dataTwo));

// 最少和最多选择项
labelFlowLayoutOne.setMinSelectCount(1); // 最少选择一个
labelFlowLayoutOne.setMaxSelectCount(1); // 最多选择一个
注意:这种情况,只是设定好了Layout,并不会初始化,因此还需要人为动态给adapter设置一个初始值。否则,刚刚开始还是不会自动选择

3,源码介绍

LabelFlowLayout 继承 FlowLayout; FlowLayout管理LabelView; LabelAdapter管理LabelFlowLayout的所有数据来源和点击事件(即:适配器模式)

LabelAdapter动态修改数据:
例如:增加选择项
public void addSelectedPosition(int position)
{
   if (!selectDeque.contains(position))
   {
      selectDeque.add(position);
      notifySelectedChange();
   }
}
1,先修改数据,2,通知Layout更新View;
更多的内容,参考源码

4, 参考:
http://blog.csdn.net/lmj623565791/article/details/48393217  -->  基本思想来源,但是源码bug较多【例如选择项的数据源有两个;此乃致命bug】;于是个人被迫改写源码

5,源码下载
欢迎大家在github上提问和交流

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值