iOS仿微信添加标签效果(shape实现)

一、 概述

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

我们上篇学习了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;
}
}

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

六、源码

点击下载

以上所述是小编给大家介绍的iOS仿微信添加标签效果(shape实现),希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对我们网站的支持!

(0)

相关推荐

  • ios动态设置lbl文字标签的高度

    复制代码 代码如下: txtlbl.font = [UIFont boldSystemFontOfSize:14.0f];     txtlbl.numberOfLines = 0;  NSString *str = @"        阿方决定设立科技特网络离开电视剧分w额两个大陆高科技了了不见了日i倒计时离开我说老师肯德基弗兰克萨江东父老将费德勒说阿方决定设立科技特网络离开电视剧分w额两个大陆高科技了了不见了日i倒计时离开我立科说老师肯德基弗兰克萨江东父老将费德勒说";    CG

  • iOS实现动态自适应标签

    先上效果图  设计要求 1.标签的宽度是按内容自适应的 2.一行显示的标签个数是动态的,放得下就放,放不下就换行 3.默认选中第一个 4.至少选中一个标签 实现思路 首先我们从这个效果上来看,这个标签是有选中和不选中状态,那我们首选的控件肯定就是用 UIButton来实现了. 这个小程度的重点就在于标签能自动换行,还是智能的,不是固定一行多少个那种,这个我们通过计算每个按钮实际宽度与屏幕的宽度进行比较就能判断是否需要换行了. 还有一点就是处理 至少选中一个标签的功能,我这里有一种方式,就是控制按

  • iOS 标签Tag列表的实现代码

    前言 1.之前项目中会有一些标签列表来显示某些特性或要求,如下图(代码实现后的效果): 2.期间也是浏览了好多其他的第三方,但是可能是没找到好的方法去寻找吧,没有找到一个合适的,况且又不是特别复杂的东西,所以就自己写了一套,但是注意因为我们项目中使用的是RAC+Mansory,所以想要使用的话需要引入这两个库=_=. 3.自己写的时候考虑的不是太多,中心思想是ViewModel做定制需求,View通过ViewModel来实现定制化UI,其他更多的是逻辑上的排版,所以不做更多赘述,自己体会Y^o^

  • iOS实现顶部标签式导航栏及下拉分类菜单

    本文实例为大家分享了iOS实现顶部标签式导航栏及下拉分类菜单的全部过程,供大家参考,具体内容如下 当内容及分类较多时,往往采用顶部标签式导航栏,例如网易新闻客户端的顶部分类导航,最近刚好有这样的应用场景,参考网络上一些demo,实现了这种导航效果,记录一些要点. 效果图(由于视频转GIF掉帧,滑动和下拉动画显得比较生硬,刚发现quickTime可以直接录制手机视频,推荐一下,很方便) 1.顶部标签式导航栏 (1)实现思路 其实就是在上下两个UIScrollView上做文章,实现联动选择切换的效果

  • iOS应用开发中UITabBarController标签栏控制器使用进阶

    做了这么长时间的ios开发了,最基本的UITabBarController和UINavigationController都用了好长时间了,总是改现成的代码,或者各种自定义控件的修改,用的都有些混乱了,呵呵.还是自己做个demo再复习一下吧,记录下来以备后续翻查. 一.UITabBarController和UINavigationController的联合使用 这种方法最常见,好像一般有tabbar都会有naviBar.一般使用, 1. 在appDelegate里面创建UITabBarContro

  • iOS仿微信添加标签效果(shape实现)

    一. 概述 可以说微信做的用户体验太棒了,可以做到老少皆宜,给个赞,我们也同时应该告诫自己,用户体验应该向微信看齐,微信就是我们的标杆,那我们今天也来仿一仿微信添加的标签功能.只能仿着做了,真是做不到微信的那种体验.甘拜下风. 我们上篇学习了shape属性的用法,那我们今天就用shape来做下微信的标签功能.先看一下效果. 我不仅用到了shape属性,还用到了翔哥的标签布局FlowLayout跟TagFlowLayout鸿洋的博客 二.效果图 三 .定义shape 添加标签 <?xml vers

  • iOS 中Swift仿微信添加提示小红点功能(无数字)

    具体内容详情如下所示: 以分类的方式实现 代码 UITabBar+Extenstion.swift fileprivate let lxfFlag: Int = 666 extension UITabBar { // MARK:- 显示小红点 func showBadgOn(index itemIndex: Int, tabbarItemNums: CGFloat = 4.0) { // 移除之前的小红点 self.removeBadgeOn(index: itemIndex) // 创建小红点

  • Android GridView仿微信添加多图效果

    本文实例为大家分享了GridView仿微信添加多图效果展示的具体代码,供大家参考,具体内容如下 栗子惯例,先上GIF 在项目中这种添加⑨图的效果应该是非常常见的,后面有个添加的按钮应该怎么实现,这也许让一部分小白抓狂了吧~来吧,淡漠带你飞,走起~~啦啦啦...... 起飞前先说下,本篇只是讲解九宫格添加图片的效果,至于选择图片的效果是别人写的库,我只是接过来做选择图片用的~ 1.首先这是用GridView实现的 xml布局就一个GridView <GridView android:id="

  • Android仿微信底部菜单栏效果

    前言 在市面上,大多数的APP都需要通过底部菜单栏来将程序的功能进行分类整理,通常都是分为3-5个大模块,从而正确有效地引导用户去使用我们的APP.实现底部菜单栏的方法也有很多种. 1.仿微信底部菜单栏(ViewPager+ImagerView+TextView) ......(其他方式后续会补充) 效果预览 首先来个开胃菜,看看实现效果: 先贴出项目所需的资源文件,这些可随个人自由更改颜色和文字 colors.xml <color name="bg_line_light_gray&quo

  • Javascript实现一个简单的输入关键字添加标签效果实例

    本文主要给大家介绍的是关于js输入关键字添加标签效果的相关内容,分享出来供大家参考学习,下面来看看详细的介绍: 实现功能: 输入关键字加空格键添加tag标签 按Backspace键删除一个标签 输入关键字后,鼠标失去焦点添加tag标签 keyWord.init方法初始化方法 展示效果: demo演示地址 示例代码 <style> .block { display:flex; flex-direction:row; align-items:center; width:500px; height:

  • iOS仿微信摇一摇动画效果加震动音效实例

    众所周知, 微信中的摇一摇功能: 搜索人/歌曲/电视,同样在一些其他类APP中也有一个摇一摇签到, 摇一摇随机选号等功能,下面以微信摇一摇功能来介绍实现原理. 对于摇一摇功能, 在iOS中系统默认为我们提供了摇一摇的功能检测API. iOS 中既然已经提供了接口, 我们直接调用就好了. #import <QuartzCore/QuartzCore.h> #import <AudioToolbox/AudioToolbox.h> 实现原理 1. 监听摇一摇方法 // 摇一摇开始 -

  • iOS仿微信图片分享界面实现代码

    分享功能目前几乎已成为很多app的标配了,其中微信,微博等app的图片分享界面设计的很棒,不仅能够展示缩略图,还可以预览删除.最近我在做一款社交分享app,其中就要实现图文分享功能,于是试着自行实现仿微信分享风格的功能. 核心思想: 主要是使用UICollectionView来动态加载分享图片内容,配合预览页面,实现动态添加和预览删除图片效果. 实现效果: 核心代码如下: 分享界面: // // PostTableViewController.h // NineShare // // Creat

  • Android实现简单底部导航栏 Android仿微信滑动切换效果

    Android仿微信滑动切换最终实现效果: 大体思路: 1. 主要使用两个自定义View配合实现; 底部图标加文字为一个自定义view,底部导航栏为一个载体,根据需要来添加底部图标; 2. 底部导航栏的设置方法类似于TabLayout的关联,View需要创建关联方法,用来关联VIewPager; 3. 通过关联方法获取ViewPager实例后,根据ViewPager页面数创建底部导航栏的图标按钮; 代码实现: 1. 新建第一个自定义View, 图标 + 文字 的底部按钮; /** * 自定义控件

  • iOS仿微信相机拍照、视频录制功能

    网上有很多自定义相机的例子,这里只是我临时写的一个iOS自定义相机(仿微信)拍照.视频录制demo,仅供参考: 用到了下面几个库: #import <AVFoundation/AVFoundation.h> #import <AssetsLibrary/AssetsLibrary.h> 在使用的时候需要在Info.plist中把相关权限写进去: Privacy - Microphone Usage Description Privacy - Photo Library Usage

  • iOS仿新闻tab标题栏效果

    iOS仿网易新闻之类的滑动标题栏,供大家参考,具体内容如下 预览 思路 两个scorllview,一个用于标题栏,一个拥有底下的page 标题栏文字和效果切换,渐变色和大小都是根据底下的page偏移量来归一化换算的 小横线直接加载标题栏所在的scorllview里面,小横线自身要有局部偏移,根据page来切换 标题栏的居中需要算一个scrollview的偏移量,小横线跟着scorllview偏移 监听scrollview的滑动和停止滑动进行相应的处理 - (void)viewDidLoad {

随机推荐