使用EditText对ListView进行过滤,并作拼音匹配

AutoCompleteTextView深度解析:从原理到高可用实战 AutoCompleteTextView是Android中典型的双模态输入组件,兼具文本输入与下拉选择能力,其核心在于Filter过滤机制、焦点状态管理及InputConnection交互链路。不同于普通EditText,它依赖严格的事件拦截顺序和线程安全的数据更新模式,尤其在中文匹配、OEM系统兼容、软键盘协同等场景下极易出现‘列表不显示’‘点击无响应’等隐蔽问题。掌握getFilter重写、setThreshold合理设置、Application Context内存规避及防抖提交等关键技术,是构建稳定搜 阅读详情

通过EditText中的输入,实现ListView过滤,主要是让adapter实现Filterable接口。可以参考SimpleAdapter的实现方式。

至于拼音过滤,在google code中有一个pinyin4android的开源项目,已经实现了对中文拼音的匹配。

效果图:


定义一个UserAdapter,对user的name字段进行过滤:

public class UserAdapter extends BaseAdapter implements Filterable{
		private List<User> users;
		public Context mContext;
		private LayoutInflater mInflater;
		private FilterDemo mFilter;
		private ArrayList<User> mDisplayData;
		//记录索引
		private ArrayList<FilterIndex> mFilterIndexs;
		
		public UserAdapter(Context context, List<User> users)
		{
			super();
			
			mContext = context;
			
			this.users = users;
			
			mDisplayData = (ArrayList<User>) users;
			
			mFilterIndexs = new ArrayList<FilterIndex>();
			mInflater = (LayoutInflater) mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
		}
		
		@Override
		public int getCount()
		{
			// TODO Auto-generated method stub
			return mDisplayData.size();
		}

		@Override
		public Object getItem(int position)
		{
			// TODO Auto-generated method stub
			
			return mDisplayData.get(position);
		}

		@Override
		public long getItemId(int position)
		{
			// TODO Auto-generated method stub
			return mDisplayData.get(position).getId();
		}

		@Override
		public View getView(final int position, View convertView, ViewGroup parent)
		{
			// TODO Auto-generated method stub

			if (convertView == null)
			  convertView = mInflater.inflate(R.layout.item, null);
			
			ViewHolder holder = new ViewHolder();
			holder.name = (TextView) convertView.findViewById(R.id.name); 
			holder.age = (TextView) convertView.findViewById(R.id.age);
			
			User user = mDisplayData.get(position);
	        
			SpannableStringBuilder ss=new SpannableStringBuilder(user.getName());
			if(!mFilterIndexs.isEmpty())
			  ss.setSpan(new ForegroundColorSpan(Color.RED),mFilterIndexs.get(position).getBegin(),mFilterIndexs.get(position).getEnd(),Spannable.SPAN_EXCLUSIVE_INCLUSIVE);
			  
			holder.name.setText(ss);
			holder.age.setText(user.getAge()+"");

			return convertView;

		}
		
		
		static class ViewHolder
		{
			TextView name;
			TextView age;
			
		}

		@Override
		public Filter getFilter()
		{
			// TODO Auto-generated method stub
			if (mFilter == null) {
	            mFilter = new FilterDemo();
	        }
	        return mFilter;
		}
		private class FilterDemo extends Filter {

	        @Override
	        protected FilterResults performFiltering(CharSequence prefix) {
	            FilterResults results = new FilterResults();
	            
	            ArrayList<String> mData = new ArrayList<String>();
	            
	            mFilterIndexs.clear();
	           
	            for(int i = 0; i < users.size(); i ++){
	                	String name = users.get(i).getName();
	                	mData.add(name);
	            }
	           
	            if (prefix == null || prefix.length() == 0) {
	            
	                results.values = mData;
	                results.count = mData.size();
	            
	            } else {
	                String prefixString = prefix.toString();
	                
	                int count = mData.size();

	                ArrayList<String> newValues = new ArrayList<String>(count);
	                
	                for (int j = 0; j < count; j++) {
	     
	                     String s = mData.get(j);
	                    
	                    //
	                    String s1 = getPinYinHeadChar(s);
	                     
	                    if(s1.contains(prefixString))
	                    {
	                         getFilterIndex(s1,prefixString);
	                		 newValues.add(s);
	                     }else
	                     if(s.contains(prefixString))
	                    {
	                   	     getFilterIndex(s,prefixString);
	                    	 newValues.add(s);
	                    }
	                      
	                }
	             
	                results.values = newValues;
	                results.count = newValues.size();
	            }
	            
	            return results;
	        }
	        @SuppressWarnings("unchecked")
			@Override
	        protected void publishResults(CharSequence constraint, FilterResults results) {
	        
	            	mDisplayData = new ArrayList<User>(results.count);
	            	
	            	for(String username:(ArrayList<String>)results.values)
	            	{
	            		  for(User userInfo:users)
	            		  {
	            			  if(userInfo.getName().equals(username)){
	            				  
	            				  mDisplayData.add(userInfo);
	            			  }
	            		  }
	            	}
	            	
	                notifyDataSetChanged();
	         
	        }
	        
	      //提取汉字的首字母
	        private String getPinYinHeadChar(String str) {
	           StringBuilder convert = new StringBuilder();
	           int length = str.length();
	           for (int j = 0; j < length; j++) {
	               char word = str.charAt(j);
	    			try {
	    				
	    				String pinyinArray = PinyinUtil.toPinyin(mContext, word);
	    				
	    				if (pinyinArray != null) {
	    	                convert.append(pinyinArray.charAt(0));
	    	            } else {
	    	                convert.append(word);
	    	            }
	    				
	    			} catch (Exception e) {
	    				e.printStackTrace();
	    			}
	              
	           }

	           return convert.toString();
	       }
	       
	        /**
	         * 获取指定字符的开始与结束的位置
	         */
	       private void getFilterIndex(String father,String child)
	       {
	    	   int start = father.indexOf(child);
	    	   int end = start+child.length();
	    	   FilterIndex filterIndex = new FilterIndex(start,end);
	    	   mFilterIndexs.add(filterIndex);
	    	   
	       }
	       
	}
		   class FilterIndex
		   {
			   private int begin;
			   private int end;
			   
			   public FilterIndex(int begin,int end)
			   {
				   this.begin = begin;
				   this.end = end;
			   }

			public int getBegin() {
				return begin;
			}

			public void setBegin(int begin) {
				this.begin = begin;
			}

			public int getEnd() {
				return end;
			}

			public void setEnd(int end) {
				this.end = end;
			}
			   
		   }
	}



然后再Activity中使用该adapter,为EditText添加addTextChangedListener:

private ListView mListView;
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        initComponent();
    }
	private void initComponent() {
		// TODO Auto-generated method stub
		EditText edit = (EditText) findViewById(R.id.edit);
		mListView = (ListView) findViewById(R.id.list_view);
		List<User> users = new ArrayList<User>();
		users.add(0, new User("zhangsan", 20));
		users.add(1, new User("lishi", 21));
		users.add(1, new User("wangwu", 21));
		users.add(1, new User("zhaoliu", 21));
		users.add(1, new User("xiaoming", 21));
		users.add(1, new User("daming", 21));
		final UserAdapter adapter = new UserAdapter(this, users);
		mListView.setAdapter(adapter);
		edit.addTextChangedListener(new TextWatcher() {
			
			@Override
			public void onTextChanged(CharSequence s, int start, int before, int count) {
				// TODO Auto-generated method stub
				
			}
			
			@Override
			public void beforeTextChanged(CharSequence s, int start, int count,
					int after) {
				// TODO Auto-generated method stub
				
			}
			
			@Override
			public void afterTextChanged(Editable s) {
				// TODO Auto-generated method stub
				adapter.getFilter().filter(s);
			}
		});
	}



Dev下拉选框拼音检索功能 Dev的下拉选框,包含拼音检索功能,能够实现每个汉字首字母拼音检索。使用方法直接给Item项添加内容。 立即下载

相关推荐

支持输入筛选的类spinner实现(AndroidStudio源码)支持拼音(首字母)搜索

使用EditText和ListView实现的可输入筛选的Spinner,输入后触发自动搜索,搜索支持原字符,汉字支持拼音全拼和首字母。代码为demo使用示例,可直接在AndroidStudio中打开使用。

Jquery插件 可编辑,可搜索,可过滤下拉框

业务需要,需要一个选择国家的下拉框,国家比较多,要实现可编辑,可过滤,可搜索功能。 网上搜索发现有一个插件可以基本实现我的功能,但不完美,所有又进行了一番改造; 原插件下载地址: https://github.com/indrimuska/jquery-editable-select 话不多说,上代码: <html> <head> <title>可编辑下拉框</title> <link rel="stylesheet" href="j

aqqyhuhjjjhjk的博客 1208

MediaPipeUnityPlugin(最新版)摇摆拳人脸识别

MediaPipeUnityPlugin(最新版)摇摆拳人脸识别

不忘初心 方得始终 2977

Android搜索功能的实现

原创文章,如有转载,请注明出处:http://blog.youkuaiyun.com/myth13141314/article/details/72926672 这里的搜索功能旨在解决本地数据搜索过滤,实现是EditText + ListView。 ListView用于展示数据, EditText用于接受输入内容,通过输入内容来过滤ListView中的数据并重新展示 过滤的实现用的是android.widget包

AntDream的程序世界 3647

Redis TLS 加密传输实战:从证书生成到安全配置

本文详细介绍了为Redis启用TLS加密传输的完整实战流程。从阐述TLS加密的必要性开始,逐步指导读者生成自签名CA和服务器证书,并深入解析Redis服务端的核心安全配置,包括端口设置、认证模式与性能优化。最后,提供了主流客户端连接示例及生产环境下的排错与运维最佳实践,帮助构建安全的Redis通信通道。

weixin_29274969的博客 515

使用GDScript(godot)生成仿杀戮尖塔地图

使用GDScript(godot)生成仿杀戮尖塔地图 extends Node2D export (PackedScene) var Ball var 被连接数 = {} # 每个怪物被下层怪物连接的数量 最多为2 var 连接1 = {} # 第一次连接的上层怪物位置 var 连接2 = {} # 第二次连接的上层怪物位置 var 怪物数量 = [0,0,0,0,0,0,0,0,0,0,0,0,0,0] # 每层怪物的数量 var 总层数 =8 # 总层数 var 怪物坐标行 = {} #

weixin_45038716的博客 3010

Android自定义搜索框(EditText)的搜索功能实现,过滤ListView

实现自定义搜索框(实际上就是一个EditText): <RelativeLayout android:id="@+id/music_search_rl" android:layout_width="match_parent" android:layout_height="30dp" android:layout_margin="5d

梦空间 4738

SAP Fiori Launchpad 自定义层文本翻译实战:精准修正 Tile、Catalog 与 Group 标题

SAP Fiori 项目中,入口层(tile/catalog/group)的翻译问题常被忽视,但其直接影响用户体验。与前端i18n不同,这些文本属于平台配置数据,需通过ABAP标准翻译流程(SE63)处理。关键步骤包括:使用/UI2/FLC定位Text ID和Configuration ID,根据前缀区分Main/Property WD Config Key,在SE63中锁定WDY_CONF_USERT2表对象进行翻译。操作时需注意使用系统源语言环境,翻译完成后可能需要清理缓存。

2007 年 ~ 2025 年,深耕 SAP 技术 18 年 170

xamarin android自定义spinner

以前弄的一个下拉框时自带的spinner,感觉好丑,实际效果实在满足不了基本的UI界面要求,还是自己动手丰衣足食,看了网上关于android中自定义spinner的文章,感觉实现原理还是比较简单,所以这里用xamarin android来实现自定义spinner样式。参考文章:http://blog.youkuaiyun.com/jdsjlzx/a...

weixin_34409357的博客 695

YOLOv12环境配置,手把手教你使用YOLOv12训练自己的数据集和推理(附YOLOv12网络结构图),全文最详细教程

YOLO 系统尊嘟太卷了吧,YOLOv11 还没完明白,YOLOv12 就重磅来袭,YOLOv12 是由纽约州立大学联合中科院在 2025年2月19 日发布,从 YOLOv12 论文题目我们大概就知道做了那些更新 ,下图是YOLOv12 在 COCO 数据集上的性能表现引入区域注意力机制(area-attention):通过引入十字形窗口自我注意机制,沿水平和垂直条纹计算注意力机制,纵横交错的注意机制。如下图所示,区域注意力采用最多简单的等分方法,将特征地图垂直或水平划分为 L 个区域。

在职AI算法工程师,擅长计算机视觉,YOLO目标检测、分割等,擅长web、pyqt界面可视化,好内容持续更新中,来这里跟大家一起学习,共同进步 6万+

如何从 VMware 官网下载最新版本的 VMware Workstation

如何从 VMware 官网下载 VMware Workstation

XiaoqiangClub的博客 5877

解决Android中Fragment调用startactivityforresult不能返回结果的问题

在android中使用Fragment启动另一个Activity并取回数据: startActivityForResult(intent, requestCode); 并重写onActivityResult(requestCode, resultCode, data)方法, 结果发现onActivityResult始终没有调用(使用的是3.2版本),此时用两种解决方法: 方法一: 使用g

snow4dev的专栏 1万+

uniapp [安卓苹果App端] - 实现支付宝支付功能+拉起支付宝app付款支付后返回跳转到原页面,详解uniApp如何唤起本机支付宝并跳转到支付页面全流程及示例源码(APP端支付宝支付,支持打包

全网最详细的uniapp支付宝支付教程,uniapp支付宝支付流程,uni-app项目在APP端使用支付宝支付功能,uniapp前端实现支付宝支付,uniapp中唤醒支付宝进行支付并返回app,uniApp调起支付宝支付失败报错,uniapp app端调支付宝支付接口,uniapp开发安卓App对接支付宝支付,uniapp苹果ios唤起支付宝支付,uniapp调用支付宝支付uniapp开发app-调用支付宝支付,uniapp开发安卓苹果app如何接入支付宝支付,UniApp中实现支付宝支付功能,支付报错,调

🏆 前端领域优质创作者 1万+

android: 10秒钟完成一个progressbar的加载

public class MainActivity extends Activity { private ProgressBar mProgressBar; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentV

snow4dev的专栏 4360

【YOLOv26 源码深度解析】第三章:YOLOv26特征融合(Neck)模块

路径聚合网络作为YOLOv26 Neck部分的核心组件,在继承特征金字塔网络(FPN)自顶向下语义传播能力的基础上,引入了自底向上的路径增强机制,构建起双向跨层特征融合体系。该架构通过建立多尺度特征间的双向信息流,有效缓解了深层网络中细节信息逐层衰减的问题,使得模型在保持高层语义理解能力的同时,能够精确定位不同尺度的目标实例。跨层深度监督的另一优势在于增强特征的尺度适应性。对于来自上层路径的特征与横向连接的特征,融合过程首先对各路特征进行加权,随后进行归一化处理,最终通过加法或拼接操作生成融合特征。

u012133341的博客 518

RU DOS版、EFI版32bit/64bit BIOS常用工具

DOS版、EFI版的RU工具,可用来查看IO、MEM、PCI、SMBIOS等资源。亲测在EFI SHELL下可用。

Android UI设计总结

1.把Button或者ImageButton的背景设为透明或者半透明: 半透明 透明.../> 其他透明度:在RGB的值前面加上数字(100以内),如#90436EEE(RGB为436EEE),#50436EEE,根据值的大小呈现不同的显示效果,值越小透明度越高。 2.设置按钮背景图片或颜色: btn.setBackgroundResource(R.drawable.comment_se

snow4dev的专栏 3218

SAP B1中文培訓教材_SDK

公司内部培训资料,对开发工具 ,DIAPI, UIAPI,Add-ON有详细解说

android知识点总结

1.抗锯齿 对于线条:mPaint.setAntiAlias(true); 对于图片:canvas.setDrawFilter(new PaintFlagsDrawFilter(0, Paint.ANTI_ALIAS_FLAG | Paint.FILTER_BITMAP_FLAG));

snow4dev的专栏 3187

android 蓝牙通讯demo

android 下蓝牙通讯demo,实现了发现蓝牙,使能蓝牙,通过蓝牙发送消息。

Outlook Express 6 (OE6) for Win7/Win8/Win10

英文版 Outlook Express6.0, 兼容Win7/Win10/WinXP,解压就可用。

Android:waiting for debugger,Eclipse DDMS error “Can't bind to local 8600 for debugger”

在Eclipse对Android进行调试,出现waiting for debugger,在Eclipse DDMS error “Can't bind to local 8600 for debugger”

snow4dev的专栏 3037

优化ListView使之滚动更平滑

相关资料:https://developer.android.com/training/improving-layouts/smooth-scrolling.html  http://stephen830.iteye.com/blog/1141532 http://trinea.iteye.com/blog/1484894 http://android-developers.blog

snow4dev的专栏 2360

Android: EditText出现StackOverflowError异常

由于需要对EditText进行实时监听,

snow4dev的专栏 2257
上一篇: 优化ListView使之滚动更平滑
下一篇: 添加一个简单Share Action
snow4dev
博客等级 码龄15年 8粉丝 28原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值