转载请注明出处: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>
- 删除标签
<?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>
-
正常标签
<?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>
- 标签选中
<?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>
以上是部分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;
}
}
“`
注释的很详细了。其实正常一步步来就按照逻辑来就可以实现,别慌,别乱,别急躁。什么功能都能实现的。
六、源码
七、欢迎大家访问我的网站和我的公众号
极客导航—程序员自己的导航网站
程序猿那点事—程序员的心灵港湾