仿微信添加标签效果

转载请注明出处:http://blog.csdn.net/xiaoyuan511

一、 概述

可以说微信做的用户体验太棒了,可以做到老少皆宜,给个赞,我们也同时应该告诫自己,用户体验应该向微信看齐,微信就是我们的标杆,那我们今天也来仿一仿微信添加的标签功能。只能仿着做了,真是做不到微信的那种体验。甘拜下风。

我们上篇学习了shape属性的用法,那我们今天就用shape来做下微信的标签功能。先看一下效果。

我不仅用到了shape属性,还用到了翔哥的标签布局FlowLayout跟TagFlowLayout鸿洋的博客

二、效果图

这里写图片描述

三 、定义shape

  • 添加标签

    <?xml version="1.0" encoding="utf-8"?>
    <shape xmlns:android="http://schemas.android.com/apk/res/android"
    android:shape="rectangle" >
    
    <corners
      android:bottomLeftRadius="30dp"
      android:bottomRightRadius="30dp"
      android:topLeftRadius="30dp"
      android:topRightRadius="30dp" />
    
    <stroke android:dashWidth="5dp" android:dashGap="2dp" android:width="1dp" android:color="#e0e0e0"  />
    
    <padding
      android:bottom="2dp"
      android:left="10dp"
      android:right="10dp"
      android:top="2dp" />
    </shape>
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 删除标签
    
    <?xml version="1.0" encoding="utf-8"?>
    <shape xmlns:android="http://schemas.android.com/apk/res/android"
    android:shape="rectangle">
    
    <corners
        android:bottomLeftRadius="30dp"
        android:bottomRightRadius="30dp"
        android:topLeftRadius="30dp"
        android:topRightRadius="30dp" />
    
    
    <solid android:color="#00FF00" />
    
    <padding
        android:bottom="2dp"
        android:left="10dp"
        android:right="10dp"
        android:top="2dp" />
    
    </shape> 
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
  • 正常标签

    
    <?xml version="1.0" encoding="utf-8"?>
    <shape xmlns:android="http://schemas.android.com/apk/res/android"
    android:shape="rectangle" >
    
    <corners
      android:bottomLeftRadius="30dp"
      android:bottomRightRadius="30dp"
      android:topLeftRadius="30dp"
      android:topRightRadius="30dp" />
    
    
    <stroke  android:width="1dp" android:color="#00FF00"  />
    
    <padding
      android:bottom="2dp"
      android:left="10dp"
      android:right="10dp"
      android:top="2dp" />
    
    </shape>  
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 标签选中
    
        <?xml version="1.0" encoding="utf-8"?>
    <shape xmlns:android="http://schemas.android.com/apk/res/android"
    android:shape="rectangle">
    
    <corners
        android:bottomLeftRadius="30dp"
        android:bottomRightRadius="30dp"
        android:topLeftRadius="30dp"
        android:topRightRadius="30dp" />
    
    
    <stroke
        android:width="1dp"
        android:color="#00FF00" />
    
    <padding
        android:bottom="2dp"
        android:left="10dp"
        android:right="10dp"
        android:top="2dp" />
    
    </shape>   
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23

    以上是部分shape定义,大家可以下载源码自己看。

四、 思路

我们可以标签大概有以下逻辑

  • 点击上面标签删除 所有标签里面更新未选中
  • 点击所有标签的某一个 上面标签添加或者删除

五、代码

“`

public class MainActivity extends AppCompatActivity {
private FlowLayout flowLayout;//上面的flowLayout
private TagFlowLayout allFlowLayout;//所有标签的TagFlowLayout
private List<String> label_list = new ArrayList<>();//上面的标签列表
private List<String> all_label_List = new ArrayList<>();//所有标签列表
final List<TextView> labels = new ArrayList<>();//存放标签
final List<Boolean> labelStates = new ArrayList<>();//存放标签状态
final Set<Integer> set = new HashSet<>();//存放选中的
private TagAdapter<String> tagAdapter;//标签适配器
private LinearLayout.LayoutParams params;
private EditText editText;


@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    initView();
    initData();
    initEdittext();
    initAllLeblLayout();
}


/**
 * 初始化View
 */
private void initView() {
    flowLayout = (FlowLayout) findViewById(R.id.id_flowlayout);
    allFlowLayout = (TagFlowLayout) findViewById(R.id.id_flowlayout_two);
    params = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
    params.setMargins(20, 20, 20, 20);
    flowLayout.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            String editTextContent = editText.getText().toString();
            if (TextUtils.isEmpty(editTextContent)) {
                tagNormal();
            } else {
                addLabel(editText);
            }
        }
    });
}
/**
 * 初始化数据
 */
private void initData(){
    //初始化上面标签
    label_list.add("同事");
    label_list.add("亲人");
    label_list.add("同学");
    label_list.add("朋友");
    label_list.add("知己");
    //初始化下面标签列表
    all_label_List.addAll(label_list);
    all_label_List.add("异性朋友");
    all_label_List.add("高中同学");
    all_label_List.add("大学同学");
    all_label_List.add("社会朋友");

    for (int i = 0; i < label_list.size() ; i++) {
        editText = new EditText(getApplicationContext());//new 一个EditText
        editText.setText(label_list.get(i));
        addLabel(editText);//添加标签
    }

}

/**
 * 初始化默认的添加标签
 */
private void initEdittext(){
    editText = new EditText(getApplicationContext());
    editText.setHint("添加标签");
    //设置固定宽度
    editText.setMinEms(4);
    editText.setTextSize(12);
    //设置shape
    editText.setBackgroundResource(R.drawable.label_add);
    editText.setHintTextColor(Color.parseColor("#b4b4b4"));
    editText.setTextColor(Color.parseColor("#000000"));
    editText.setLayoutParams(params);
    //添加到layout中
    flowLayout.addView(editText);
    editText.addTextChangedListener(new TextWatcher() {
        @Override
        public void beforeTextChanged(CharSequence s, int start, int count, int after) {

        }

        @Override
        public void onTextChanged(CharSequence s, int start, int before, int count) {
            tagNormal();
        }

        @Override
        public void afterTextChanged(Editable s) {

        }
    });

}

/**
 * 初始化所有标签列表
 */
private void initAllLeblLayout() {
    //初始化适配器
    tagAdapter = new TagAdapter<String>(all_label_List) {
        @Override
        public View getView(FlowLayout parent, int position, String s) {
            TextView tv = (TextView) getLayoutInflater().inflate(R.layout.flag_adapter,
                    allFlowLayout, false);
            tv.setText(s);
            return tv;
        }
    };

    allFlowLayout.setAdapter(tagAdapter);

    //根据上面标签来判断下面的标签是否含有上面的标签
    for (int i = 0; i < label_list.size(); i++) {
        for (int j = 0; j < all_label_List.size(); j++) {
            if (label_list.get(i).equals(
                    all_label_List.get(j))) {
                tagAdapter.setSelectedList(i);//设为选中
            }
        }
    }
    tagAdapter.notifyDataChanged();


    //给下面的标签添加监听
    allFlowLayout.setOnTagClickListener(new TagFlowLayout.OnTagClickListener() {
        @Override
        public boolean onTagClick(View view, int position, FlowLayout parent) {
            if (labels.size() == 0) {
                editText.setText(all_label_List.get(position));
                addLabel(editText);
                return false;
            }
            List<String> list = new ArrayList<>();
            for (int i = 0; i < labels.size(); i++) {
                list.add(labels.get(i).getText().toString());
            }
            //如果上面包含点击的标签就删除
            if (list.contains(all_label_List.get(position))) {
                for (int i = 0; i < list.size(); i++) {
                    if (all_label_List.get(position).equals(list.get(i))) {
                        flowLayout.removeView(labels.get(i));
                        labels.remove(i);
                    }
                }

            } else {
                editText.setText(all_label_List.get(position));
                addLabel(editText);
            }

            return false;
        }
    });

    //已经选中的监听
    allFlowLayout.setOnSelectListener(new TagFlowLayout.OnSelectListener() {

        @Override
        public void onSelected(Set<Integer> selectPosSet) {
            set.clear();
            set.addAll(selectPosSet);
        }
    });
}

/**
 * 添加标签
 * @param editText
 * @return
 */
private boolean addLabel(EditText editText) {
    String editTextContent = editText.getText().toString();
    //判断输入是否为空
    if (editTextContent.equals(""))
        return true;
    //判断是否重复
    for (TextView tag : labels) {
        String tempStr = tag.getText().toString();
        if (tempStr.equals(editTextContent)) {
            editText.setText("");
            editText.requestFocus();
            return true;
        }
    }
    //添加标签
    final TextView temp = getTag(editText.getText().toString());
    labels.add(temp);
    labelStates.add(false);
    //添加点击事件,点击变成选中状态,选中状态下被点击则删除
    temp.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            int curIndex = labels.indexOf(temp);
            if (!labelStates.get(curIndex)) {
                //显示 ×号删除
                temp.setText(temp.getText() + " ×");
                temp.setBackgroundResource(R.drawable.label_del);
                temp.setTextColor(Color.parseColor("#ffffff"));
                //修改选中状态
                labelStates.set(curIndex, true);
            } else {
                delByTest(temp.getText().toString());
                flowLayout.removeView(temp);
                labels.remove(curIndex);
                labelStates.remove(curIndex);
                for (int i = 0; i < label_list.size(); i++) {
                    for (int j = 0; j < labels.size(); j++) {
                        if (label_list.get(i).equals(
                                labels.get(j).getText())) {
                            tagAdapter.setSelectedList(i);
                        }
                    }
                }
                tagAdapter.notifyDataChanged();
            }
        }
    });
    flowLayout.addView(temp);
    //让输入框在最后一个位置上
    editText.bringToFront();
    //清空编辑框
    editText.setText("");
    editText.requestFocus();
    return true;

}


/**
 * 根据字符删除标签
 * @param text
 */
private void delByTest(String text) {

    for (int i = 0; i < all_label_List.size(); i++) {
        String a = all_label_List.get(i) + " ×";
        if (a.equals(text)) {
            set.remove(i);
        }
    }
    tagAdapter.setSelectedList(set);//重置选中的标签

}


/**
 * 标签恢复到正常状态
 */
private void tagNormal() {
    //输入文字时取消已经选中的标签
    for (int i = 0; i < labelStates.size(); i++) {
        if (labelStates.get(i)) {
            TextView tmp = labels.get(i);
            tmp.setText(tmp.getText().toString().replace(" ×", ""));
            labelStates.set(i, false);
            tmp.setBackgroundResource(R.drawable.label_normal);
            tmp.setTextColor(Color.parseColor("#00FF00"));
        }
    }
}


/**
 * 创建一个正常状态的标签
 * @param label
 * @return
 */
private TextView getTag(String label) {
    TextView textView = new TextView(getApplicationContext());
    textView.setTextSize(12);
    textView.setBackgroundResource(R.drawable.label_normal);
    textView.setTextColor(Color.parseColor("#00FF00"));
    textView.setText(label);
    textView.setLayoutParams(params);
    return textView;
}
  }

“` 
注释的很详细了。其实正常一步步来就按照逻辑来就可以实现,别慌,别乱,别急躁。什么功能都能实现的。

六、源码

点击下载

七、欢迎大家访问我的网站和我的公众号

极客导航—程序员自己的导航网站

极客导航

程序猿那点事—程序员的心灵港湾 
关注我

阅读更多
想对作者说点什么?

博主推荐

换一批

没有更多推荐了,返回首页