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

通过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);
			}
		});
	}



  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
要实现在 EditText 中输入内容并展示 ListView 的效果,可以按照以下步骤: 1. 在布局文件中添加一个 EditText 和一个 ListView。 2. 创建一个适配器 Adapter,将数据和布局文件绑定。 3. 在 Activity 中获取 EditTextListView 的实例,并为 EditText 添加文本改变监听器。 4. 在文本改变监听器中获取 EditText 的内容,并根据内容过滤数据源。 5. 将过滤后的数据源更新到适配器中,并调用适配器的 notifyDataSetChanged() 方法刷新 ListView。 以下是代码示例: 布局文件: ``` <LinearLayout android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical"> <EditText android:id="@+id/et_search" android:layout_width="match_parent" android:layout_height="wrap_content" android:hint="Search..."/> <ListView android:id="@+id/lv_search_result" android:layout_width="match_parent" android:layout_height="match_parent"/> </LinearLayout> ``` Adapter: ``` public class MyAdapter extends BaseAdapter { private List<String> mData; private LayoutInflater mInflater; public MyAdapter(Context context, List<String> data) { mData = data; mInflater = LayoutInflater.from(context); } @Override public int getCount() { return mData.size(); } @Override public String getItem(int position) { return mData.get(position); } @Override public long getItemId(int position) { return position; } @Override public View getView(int position, View convertView, ViewGroup parent) { if (convertView == null) { convertView = mInflater.inflate(R.layout.item_listview, parent, false); } TextView tv = convertView.findViewById(R.id.tv_item); tv.setText(getItem(position)); return convertView; } } ``` Activity: ``` public class MainActivity extends AppCompatActivity { private EditText mEtSearch; private ListView mLvSearchResult; private List<String> mData; private MyAdapter mAdapter; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); mEtSearch = findViewById(R.id.et_search); mLvSearchResult = findViewById(R.id.lv_search_result); mData = new ArrayList<>(Arrays.asList("Apple", "Banana", "Cherry", "Durian", "Elderberry")); mAdapter = new MyAdapter(this, mData); mLvSearchResult.setAdapter(mAdapter); mEtSearch.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) { String keyword = s.toString().toLowerCase(Locale.getDefault()); List<String> filteredData = new ArrayList<>(); for (String item : mData) { if (item.toLowerCase(Locale.getDefault()).contains(keyword)) { filteredData.add(item); } } mAdapter = new MyAdapter(MainActivity.this, filteredData); mLvSearchResult.setAdapter(mAdapter); mAdapter.notifyDataSetChanged(); } @Override public void afterTextChanged(Editable s) {} }); } } ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值