热门标签 | HotTags
当前位置:  开发笔记 > 运维 > 正文

Android仿QQ个人标签添加与删除功能

这篇文章主要为大家详细介绍了Android仿QQ个人标签添加与删除功能,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

最近在公司项目开发中,有一个类似于QQ个人标签的需求要完成,具体包括个人标签的添加,删除,添加过程中重复的标签会提示用户,不能够进行添加。先给大家看一下效果图。

点击标签按钮,弹出标签选择的页面,显示所有的标签;点击全部标签里面的item,选择的标签会显示在上方;再次点击相同的标签进行添加,会提示用户“标签已存在,请重新添加”;点击上方已经选择好的标签,进行删除操作

业务逻辑就是这样,下面是具体实现过程:

一、界面布局:



  
  
 

 

  
 

 

关键布局就是两个Gridview,其中属性依次设置的是ID,高宽,边距,水平边距,列数,隐藏滚动条,缩放与列宽大小同步,垂直边距。item里面的布局就是textview,背景是一个自定义的边框。

二、Gridview的适配器:

public class FragLabelGridViewAdapter extends BaseAdapter {

 class ViewHolder {
  @ViewInject(R.id.gv_label_txt)
  public TextView label;
 }

 private Context context;
 private LayoutInflater inflater;
 private List labels;

 public FragLabelGridViewAdapter(List labels, Context context) {
  this.cOntext= context;
  inflater = LayoutInflater.from(context);
  this.labels = labels;

 }

 @Override
 public int getCount() {
  return labels.size();
 }

 @Override
 public Object getItem(int position) {
  return (position);
 }

 @Override
 public long getItemId(int id) {
  // TODO Auto-generated method stub
  return id;
 }

 @Override
 public View getView(int position, View convertView, ViewGroup parent) {
  ViewHolder viewHolder;
  if (cOnvertView== null) {
   cOnvertView= inflater.inflate(R.layout.gv_item_label, null);
   viewHolder = new ViewHolder();
   ViewUtils.inject(viewHolder, convertView);
   convertView.setTag(viewHolder);
  } else {
   viewHolder = (ViewHolder) convertView.getTag();
  }
  viewHolder.label.setText(labels.get(position));
  return convertView;
 }

}

核心就是使用viewHolder来优化Gridview,原理就是convertView的复用:当第一次创建convertView对象时,便把item的子View控件对象实例化出来并保存到ViewHolder对象中(这里使用了Xutils的注解)。然后用convertView的setTag将viewHolder对象设置到Tag中, 当以后再次加载ListView的item时便可以直接从Tag中取出ViewHolder对象,不需要每次都去获取item的子控件对象。这样达到复用的目的,大大提高了性能。

三、主界面的代码:

public class FragmentLabel extends Fragment {

 @ViewInject(R.id.label_gv)
 GridView labelGridview;
 @ViewInject(R.id.label_check_gv)
 GridView labelCheckGridview;
 private Context context;
 private FragLabelGridViewAdapter adapter;
 private FragLabelCheckGridViewAdapter checkAdapter;
 // 所有标签
 private List labels = new ArrayList();
 // 已选标签
 private List checkLabels = new ArrayList();

 public View onCreateView(LayoutInflater inflater, ViewGroup container,
   Bundle savedInstanceState) {

  View view = inflater.inflate(R.layout.fragment_label, container, false);
  ViewUtils.inject(this, view);
  cOntext= getActivity().getApplicationContext();
  return view;

 }

 @Override
 public void onActivityCreated(Bundle savedInstanceState) {
  // TODO Auto-generated method stub
  super.onActivityCreated(savedInstanceState);
  initviews();
 }

首先是通过注解来进行组件的声明,效果与findviewbyid()一样。然后就是两个Gridview的适配器的声明,接下来就是模拟Gridview里面的数据进行操作

private void initviews() {
  labels.add("高血压");
  labels.add("糖尿病");
  labels.add("肺炎");
  labels.add("肝炎");
  labels.add("高血脂");
  labels.add("心脏病");
  labels.add("中暑");
  labels.add("肺炎");
  labels.add("感冒");
  labels.add("高血脂");
  labels.add("胃病");
  labels.add("糖尿病");
  labels.add("肺炎");
  labels.add("肝炎");
  labels.add("高血脂");
  labels.add("高血压");
  labels.add("糖尿病");
  labels.add("肺炎");
  labels.add("肝炎");
  labels.add("高血脂");
  labels.add("高血压");
  labels.add("糖尿病");
  labels.add("肺炎");

  adapter = new FragLabelGridViewAdapter(labels, context);
  labelGridview.setAdapter(adapter);
  labelGridview.setOnItemClickListener(new OnItemClickListener() {

   @Override
   public void onItemClick(AdapterView<&#63;> arg0, View arg1,
     int position, long arg3) {
    for (int i = 0; i  arg0, View arg1,
     int position, long arg3) {
    checkLabels.remove(position);
    refresh();
   }
  });

 }

 private void refresh() {
  checkAdapter.setLabels(checkLabels);
  checkAdapter.notifyDataSetChanged();
 }
}

首先往list集合添加数据,这里都是模拟的数据,实际情况数据都会从服务器获取。通过构造方法传递了两个参数来实例化适配器,并给Gridview绑定适配器。

给下面Gridview的item绑定监听器,处理点击添加操作。点击事件里面,首先要进行标签唯一性的判断,遍历上面Gridview的list集合,如果与点击item的值一样,会提示用户“标签存在”,如果标签不存在,则会将数据添加在上面的Gridview的list中。最后执行refresh方法,将数据传递给adapter,然后调用notifyDataSetChanged()方法,这样选择的标签会自动出现在上面,无需刷新操作。

给上面Gridview的item绑定监听器,处理点击删除操作,调用的是list的remove(position)方法,删除方法执行以后,再调用一下刷新方法。最后运行的效果和刚开始的图片一样。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。


推荐阅读
  • 理解和应用HTTP请求中的转发与重定向机制
    在HTTP请求处理过程中,客户端发送请求(通常简称为req),服务器进行相应处理后返回响应(通常简称为res)。理解和应用客户端的转发与重定向机制是前端开发的重要内容。这两种机制在Web开发中具有关键作用,能够有效管理和优化用户请求的处理流程。转发机制允许服务器内部将请求传递给另一个资源,而重定向则指示客户端向新的URL发起新的请求,从而实现页面跳转或资源更新。掌握这些技术有助于提升应用的性能和用户体验。 ... [详细]
  • 润乾报表JNDI配置异常分析与解决方法
    在使用润乾报表时,通过JNDI连接数据源是常见的配置方式。本文详细分析了JNDI配置异常的原因,并提供了具体的解决方法。重点讨论了JNDI名称在三个关键位置的配置:1. Tomcat或应用服务器的数据源配置(以Tomcat为例);2. 润乾报表中的数据源配置;3. 应用程序代码中的JNDI名称引用。通过这些步骤,可以有效解决JNDI配置异常问题,确保报表系统的稳定运行。 ... [详细]
  • Syncnavigator激活工具及破解方法详解
    本文详细介绍了Syncnavigator激活工具的使用方法及其破解技巧。用户可以通过访问官方网站www.SyncNavigator.CN获取相关资源,并通过客服QQ 1793040获得技术支持和帮助。此外,文章还提供了详细的步骤说明和常见问题解答,以确保用户能够顺利激活并使用Syncnavigator软件。 ... [详细]
  • 《我的世界》Java版与Windows 10版(基岩版)有何不同?
    《我的世界》Java版与Windows 10版(基岩版)有何不同? ... [详细]
  • 在SQL Server 2008数据库迁移过程中,备份方法是一种高效且可靠的导出手段。本文详细介绍了如何利用备份功能实现数据的快速迁移,并提供了具体的步骤和注意事项,适合Golang程序员和数据库管理员参考。 ... [详细]
  • Netty框架中运用Protobuf实现高效通信协议
    在Netty框架中,通过引入Protobuf来实现高效的通信协议。为了使用Protobuf,需要先准备好环境,包括下载并安装Protobuf的代码生成器`protoc`以及相应的源码包。具体资源可从官方下载页面获取,确保版本兼容性以充分发挥其性能优势。此外,配置好开发环境后,可以通过定义`.proto`文件来自动生成Java类,从而简化数据序列化和反序列化的操作,提高通信效率。 ... [详细]
  • 在网络故障排查中,tcpdump 是一款强大的工具,尤其在 Linux 环境下。尽管开发环境中问题较少,但在测试或生产环境中,往往会遇到各种难以预料的异常情况。通过在问题发生的环境中启用 tcpdump 进行抓包,并重现问题,可以获取到宝贵的原始数据,为问题的诊断提供关键线索。本文将详细介绍如何使用 tcpdump 进行实战操作,帮助读者掌握这一技能。 ... [详细]
  • TensorFlow Lite在移动设备上的部署实践与优化笔记
    近期在探索如何将服务器端的模型迁移到移动设备上,并记录了一些关键问题和解决方案。本文假设读者具备以下基础知识:了解TensorFlow的计算图(Graph)、图定义(GraphDef)和元图定义(MetaGraphDef)。此外,文中还详细介绍了模型转换、性能优化和资源管理等方面的实践经验,为开发者提供有价值的参考。 ... [详细]
  • 探索偶数次幂二项式系数的求和方法及其数学意义 ... [详细]
  • 在VMware虚拟机中部署带有中文图形界面的CentOS 7 Linux系统
    本文详细介绍了在VMware虚拟机中部署带有中文图形界面的CentOS 7 Linux系统的步骤。首先,通过“文件”菜单选择“新建虚拟机”并进入自定义设置。接着,在硬盘兼容性选项中选择默认设置。为了更好地进行Linux操作系统的安装练习,建议选择稍后安装操作系统,并在虚拟机安装完成后,根据实际需求删除不必要的硬件组件。此外,本文还提供了详细的配置参数和注意事项,帮助用户顺利完成整个部署过程。 ... [详细]
  • 源代码是构建网站的基础,涵盖了网站程序的所有代码、文件和目录结构。掌握源代码意味着完全控制网站的所有权。在传统自助建站平台中,由于采用SAAS模式,源代码通常不对外开放,用户实际上每年支付的费用仅是为了使用这些平台提供的服务,而无法获得真正的代码所有权。相比之下,米拓源代码提供了全面的技术细节和实现方法,使开发者能够深入了解并自主定制网站功能,确保了更高的灵活性和安全性。 ... [详细]
  • 设计实战 | 10个Kotlin项目深度解析:首页模块开发详解
    设计实战 | 10个Kotlin项目深度解析:首页模块开发详解 ... [详细]
  • 在分析Socket服务器程序接收中文数据时出现的乱码问题时,我们发现客户端使用C#编写的数据在返回时能够正常显示。本文详细探讨了该问题的成因,并提出了一种有效的解决方案。通过调整字符编码设置和优化数据传输格式,确保了中文数据在传输过程中的完整性与正确性。具体实现代码包括对Socket读取事件的处理,确保数据以正确的编码格式进行解析和显示。 ... [详细]
  • Python 实战:异步爬虫(协程技术)与分布式爬虫(多进程应用)深入解析
    本文将深入探讨 Python 异步爬虫和分布式爬虫的技术细节,重点介绍协程技术和多进程应用在爬虫开发中的实际应用。通过对比多进程和协程的工作原理,帮助读者理解两者在性能和资源利用上的差异,从而在实际项目中做出更合适的选择。文章还将结合具体案例,展示如何高效地实现异步和分布式爬虫,以提升数据抓取的效率和稳定性。 ... [详细]
  • 探讨上传下载 API 的常见问题及解决方案 ... [详细]
author-avatar
神秘的绝代双角
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有