- 浏览: 249784 次
- 性别:
- 来自: 内蒙古
文章分类
- 全部博客 (237)
- Android 功能实现 (31)
- sql数据库的学习 (8)
- Android 美化界面 (2)
- Android 优化 (1)
- Ruby on Rails 方面 (45)
- git 方面的学习 (1)
- ruby 编程的琢磨 (13)
- linux下工具软件 (13)
- 操作系统的学习 (40)
- 非技术 (13)
- 网站开发 (18)
- js 学习笔记 (19)
- css学习 (5)
- 回顾总结 (2)
- Delphi 学习 (2)
- C 语言学习笔记 (1)
- 数据结构 (1)
- node js 学习 (6)
- 设计模式 (2)
- mongdb 学习笔记 (0)
- 软件服务 (3)
- osx系统 (4)
- 搜索引擎 (1)
- 测试工具 (1)
- Aliyun (1)
- 前端JS (1)
- python学习 (0)
- iOS系统 (1)
- 分布式锁 (1)
- 开发工具 (0)
- java代码 (2)
- java (1)
最新评论
-
jiguanghover:
写的不错,收藏一下
Ubuntu下RVM, Ruby, rails安装详细 和 卸载 -
maoghj:
回顾总结(二) -
yun2223:
对楼主表示感谢
Android控件开发之Gallery3D效果 -
zw_lovec:
说清楚点吧 亲 加点注释
out of memory -
lzyfn123:
http://www.iteye.com/images/smi ...
ruby-string 字符串的学习
AutoCompleteTextView
AutoCompleteTextView具有输入提示的功能,但是它的这种提示不适合对股票列表的过滤,如果你玩过股票软件,就会知道只要输入股票名称的首字母或股票代码就会出现符合匹配的股票,这种过滤怎么实现呢?
还有个问题,汉字具有多音字,如何实现多音字的匹配,比如“长江证券”,无论你输入“cjzq”或者“zjzq”都会匹配到它,这都是需要解决的问题!
匹配的关键在于重写BaseAdapter,让它实现Filterable接口,重写其中的getFilter(),如果你参照ArrayAdaper源码的话,写起来就会容易很多,事实上我就是这么做的,^o^
下面看一下源码:
- package com.ql.util;
- import java.util.*;
- import android.content.Context;
- import android.util.Log;
- import android.view.*;
- import android.widget.BaseAdapter;
- import android.widget.Filter;
- import android.widget.Filterable;
- import android.widget.TextView;
- public class SearchAdapter<T> extends BaseAdapter implements Filterable {
- private List<T> mObjects;
- private List<Set<String>> pinyinList; //支持多音字,类似:{{z,c},{j},{z},{q,x}}的集合
- private final Object mLock = new Object();
- private int mResource;
- private int mFieldId = 0 ;
- private Context mContext;
- private ArrayList<T> mOriginalValues;
- private ArrayFilter mFilter;
- private LayoutInflater mInflater;
- public static final int ALL=- 1 ; //全部
- private int maxMatch= 10 ; //最多显示多少个可能选项
- //支持多音字
- public SearchAdapter(Context context, int textViewResourceId, T[] objects, int maxMatch) {
- // TODO Auto-generated constructor stub
- init(context, textViewResourceId, 0 , Arrays.asList(objects));
- this .pinyinList = getHanziSpellList(objects);
- this .maxMatch=maxMatch;
- }
- public SearchAdapter(Context context, int textViewResourceId, List<T> objects, int maxMatch) {
- // TODO Auto-generated constructor stub
- init(context, textViewResourceId, 0 , objects);
- this .pinyinList = getHanziSpellList(objects);
- this .maxMatch=maxMatch;
- }
- private void init(Context context, int resource, int textViewResourceId,List<T> objects) {
- mContext = context;
- mInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
- mResource = resource;
- mObjects = objects;
- mFieldId = textViewResourceId;
- }
- /**
- * 获得汉字拼音首字母列表
- */
- private List<Set<String>> getHanziSpellList(T[] hanzi){
- List<Set<String>> listSet=new ArrayList<Set<String>>();
- PinYin4j pinyin=new PinYin4j();
- for ( int i= 0 ;i<hanzi.length;i++){
- listSet.add(pinyin.getPinyin(hanzi[i].toString()));
- }
- return listSet;
- }
- /**
- * 获得汉字拼音首字母列表
- */
- private List<Set<String>> getHanziSpellList(List<T> hanzi){
- List<Set<String>> listSet=new ArrayList<Set<String>>();
- PinYin4j pinyin=new PinYin4j();
- for ( int i= 0 ;i<hanzi.size();i++){
- listSet.add(pinyin.getPinyin(hanzi.get(i).toString()));
- }
- return listSet;
- }
- public int getCount() {
- return mObjects.size();
- }
- public T getItem( int position) {
- return mObjects.get(position);
- }
- public int getPosition(T item) {
- return mObjects.indexOf(item);
- }
- public long getItemId( int position) {
- return position;
- }
- public View getView( int position, View convertView, ViewGroup parent) {
- return createViewFromResource(position, convertView, parent, mResource);
- }
- private View createViewFromResource( int position, View convertView,
- ViewGroup parent, int resource) {
- View view;
- TextView text;
- if (convertView == null ) {
- view = mInflater.inflate(resource, parent, false );
- } else {
- view = convertView;
- }
- try {
- if (mFieldId == 0 ) {
- text = (TextView) view;
- } else {
- text = (TextView) view.findViewById(mFieldId);
- }
- } catch (ClassCastException e) {
- Log.e("ArrayAdapter" ,
- "You must supply a resource ID for a TextView" );
- throw new IllegalStateException(
- "ArrayAdapter requires the resource ID to be a TextView" , e);
- }
- text.setText(getItem(position).toString());
- return view;
- }
- public Filter getFilter() {
- if (mFilter == null ) {
- mFilter = new ArrayFilter();
- }
- return mFilter;
- }
- private class ArrayFilter extends Filter {
- @Override
- protected FilterResults performFiltering(CharSequence prefix) {
- FilterResults results = new FilterResults();
- if (mOriginalValues == null ) {
- synchronized (mLock) {
- mOriginalValues = new ArrayList<T>(mObjects); //
- }
- }
- if (prefix == null || prefix.length() == 0 ) {
- synchronized (mLock) {
- // ArrayList<T> list = new ArrayList<T>();//无
- ArrayList<T> list = new ArrayList<T>(mOriginalValues); //List<T>
- results.values = list;
- results.count = list.size();
- }
- } else {
- String prefixString = prefix.toString().toLowerCase();
- final ArrayList<T> hanzi = mOriginalValues; //汉字String
- final int count = hanzi.size();
- final Set<T> newValues = new HashSet<T>(count); //支持多音字,不重复
- for ( int i = 0 ; i < count; i++) {
- final T value = hanzi.get(i); //汉字String
- final String valueText = value.toString().toLowerCase(); //汉字String
- final Set<String> pinyinSet=pinyinList.get(i); //支持多音字,类似:{z,c}
- Iterator iterator= pinyinSet.iterator();//支持多音字
- while (iterator.hasNext()) { //支持多音字
- final String pinyin = iterator.next().toString().toLowerCase(); //取出多音字里的一个字母
- if (pinyin.indexOf(prefixString)!=- 1 ) { //任意匹配
- newValues.add(value);
- }
- else if (valueText.indexOf(prefixString)!=- 1 ) { //如果是汉字则直接添加
- newValues.add(value);
- }
- }
- if (maxMatch> 0 ){ //有数量限制
- if (newValues.size()>maxMatch- 1 ){ //不要太多
- break ;
- }
- }
- }
- List<T> list=Set2List(newValues);//转成List
- results.values = list;
- results.count = list.size();
- }
- return results;
- }
- protected void publishResults(CharSequence constraint,FilterResults results) {
- mObjects = (List<T>) results.values;
- if (results.count > 0 ) {
- notifyDataSetChanged();
- } else {
- notifyDataSetInvalidated();
- }
- }
- }
- //List Set 相互转换
- public <T extends Object> Set<T> List2Set(List<T> tList) {
- Set<T> tSet = new HashSet<T>(tList);
- //TODO 具体实现看需求转换成不同的Set的子类。
- return tSet;
- }
- public <T extends Object> List<T> Set2List(Set<T> oSet) {
- List<T> tList = new ArrayList<T>(oSet);
- // TODO 需要在用到的时候另外写构造,根据需要生成List的对应子类。
- return tList;
- }
- }
在源码当中使用了PinYin4j去获得汉字的首字母,由于可能是多音字,所以将每个汉字的拼音都放在了Set中。当然PinYin4j很多强大的功能在这里都用不到,所以被我统统去掉了,这样大大提高了匹配效率。再看一下PinYin4j.java:
- package com.ql.util;
- import java.util.Arrays;
- import java.util.HashSet;
- import java.util.Set;
- public class PinYin4j {
- public PinYin4j(){
- }
- /**
- * 字符串集合转换字符串(逗号分隔)
- *
- * @author wyh
- * @param stringSet
- * @return
- */
- public String makeStringByStringSet(Set<String> stringSet) {
- StringBuilder str = new StringBuilder();
- int i = 0 ;
- for (String s : stringSet) {
- if (i == stringSet.size() - 1 ) {
- str.append(s);
- } else {
- str.append(s + "," );
- }
- i++;
- }
- return str.toString().toLowerCase();
- }
- /**
- * 获取拼音集合
- *
- * @author wyh
- * @param src
- * @return Set<String>
- */
- public Set<String> getPinyin(String src) {
- char [] srcChar;
- srcChar = src.toCharArray();
- //1:多少个汉字
- //2:每个汉字多少种读音
- String[][] temp = new String[src.length()][];
- for ( int i = 0 ; i < srcChar.length; i++) {
- char c = srcChar[i];
- // 是中文或者a-z或者A-Z转换拼音(我的需求,是保留中文或者a-z或者A-Z)
- if (String.valueOf(c).matches( "[\\u4E00-\\u9FA5]+" )) {
- String[] t = PinyinHelper.getUnformattedHanyuPinyinStringArray(c);
- temp[i] = new String[t.length];
- for ( int j= 0 ;j<t.length;j++){
- temp[i][j]=t[j].substring(0 , 1 ); //获取首字母
- }
- } else if ((( int ) c >= 65 && ( int ) c <= 90 )
- || ((int ) c >= 97 && ( int ) c <= 122 )||c>= 48 &&c<= 57 ||c== 42 ) { //a-zA-Z0-9*
- temp[i] = new String[] { String.valueOf(srcChar[i]) };
- } else {
- temp[i] = new String[] { "null!" };
- }
- }
- String[] pingyinArray = paiLie(temp);
- return array2Set(pingyinArray); //为了去掉重复项
- }
- /*
- * 求2维数组所有排列组合情况
- * 比如:{{1,2},{3},{4},{5,6}}共有2中排列,为:1345,1346,2345,2346
- */
- private String[] paiLie(String[][] str){
- int max= 1 ;
- for ( int i= 0 ;i<str.length;i++){
- max*=str[i].length;
- }
- String[] result=new String[max];
- for ( int i = 0 ; i < max; i++){
- String s = "" ;
- int temp = 1 ; //注意这个temp的用法。
- for ( int j = 0 ; j < str.length; j++){
- temp *= str[j].length;
- s += str[j][i / (max / temp) % str[j].length];
- }
- result[i]=s;
- }
- return result;
- }
- public static <T extends Object> Set<T> array2Set(T[] tArray) {
- Set<T> tSet = new HashSet<T>(Arrays.asList(tArray));
- // TODO 没有一步到位的方法,根据具体的作用,选择合适的Set的子类来转换。
- return tSet;
- }
- /**
- * @param args
- */
- public static void main(String[] args) {
- //nongyeyinheng,nongyeyinhang,nongyeyinxing
- PinYin4j t=new PinYin4j();
- String str = "农业银行1234567890abcdefghijklmnopqrstuvwxyz*" ;
- System.out.println(t.makeStringByStringSet(t.getPinyin(str)));
- }
- }
这只是一个工具类,它使用到了PinyinHelper,PinyinHelper是加载字库文件用的,字库文件为/assets/unicode_to_hanyu_pinyin.txt,里面每一个汉字都对应着几个读音。
- package com.ql.util;
- import java.io.BufferedInputStream;
- import java.io.FileNotFoundException;
- import java.io.IOException;
- import java.util.Properties;
- public class PinyinHelper{
- private static PinyinHelper instance;
- private Properties properties = null ;
- public static String[] getUnformattedHanyuPinyinStringArray( char ch){
- return getInstance().getHanyuPinyinStringArray(ch);
- }
- private PinyinHelper(){
- initResource();
- }
- public static PinyinHelper getInstance(){
- if (instance== null ){
- instance = new PinyinHelper();
- }
- return instance;
- }
- private void initResource(){
- try {
- final String resourceName = "/assets/unicode_to_hanyu_pinyin.txt" ;
- // final String resourceName = "/assets/unicode_py.ini";
- properties=new Properties();
- properties.load(getResourceInputStream(resourceName));
- } catch (FileNotFoundException ex){
- ex.printStackTrace();
- } catch (IOException ex){
- ex.printStackTrace();
- }
- }
- private BufferedInputStream getResourceInputStream(String resourceName){
- return new BufferedInputStream(PinyinHelper. class .getResourceAsStream(resourceName));
- }
- private String[] getHanyuPinyinStringArray( char ch){
- String pinyinRecord = getHanyuPinyinRecordFromChar(ch);
- if ( null != pinyinRecord){
- int indexOfLeftBracket = pinyinRecord.indexOf(Field.LEFT_BRACKET);
- int indexOfRightBracket = pinyinRecord.lastIndexOf(Field.RIGHT_BRACKET);
- String stripedString = pinyinRecord.substring(indexOfLeftBracket
- + Field.LEFT_BRACKET.length(), indexOfRightBracket);
- return stripedString.split(Field.COMMA);
- } else
- return null ;
- }
- private String getHanyuPinyinRecordFromChar( char ch){
- int codePointOfChar = ch;
- String codepointHexStr = Integer.toHexString(codePointOfChar).toUpperCase();
- String foundRecord = properties.getProperty(codepointHexStr);
- return foundRecord;
- }
- class Field{
- static final String LEFT_BRACKET = "(" ;
- static final String RIGHT_BRACKET = ")" ;
- static final String COMMA = "," ;
- }
- }
至于解析字库,比如有一个汉字是这样的格式:4E01 (ding1,zheng1),保存
到String[]当中就是{"ding1","zheng1"}这样的。但是这样的话到了PinYin4j中还需要使用substring(0,1)截
取首字母,效率有些低了,事实上文件中完全可以采用这样的格式存储:E01 (d,z),直接存汉字的首字母就行了,这个另论!
最后,看看使用方法:
- public class QuickSearchActivity extends Activity {
- private static final String tag= "QuickSearchActivity" ;
- private AutoCompleteTextView search ;
- private SlidingDrawer mDrawer;
- public SearchAdapter adapter= null ; //
- //需要读取
- public String[] hanzi = new String[] {
- "长江证券100002" , "长江证券100001" , "农业银行200001" , "工商银行300001" ,
- "招商银行100001" , "建设银行100001" , "中国银行100002" , "华夏银行500002" ,
- "上海银行100010" , "浦发银行200009"
- };
- /** Called when the activity is first created. */
- @Override
- public void onCreate(Bundle savedInstanceState) {
- super .onCreate(savedInstanceState);
- setContentView(R.layout.main);
- initViews();
- }
- private void initViews(){
- search = (AutoCompleteTextView) findViewById(R.id.search);
- search.setOnItemClickListener(new OnItemClickListener() {
- @Override
- public void onItemClick(AdapterView<?> arg0, View arg1, int position,
- long id) {
- // TODO Auto-generated method stub
- Log.d(tag, "onItemClick:" +position);
- }
- });
- search.setThreshold(1 );
- adapter = new SearchAdapter<String>( this ,
- android.R.layout.simple_dropdown_item_1line, hanzi,SearchAdapter.ALL);//速度优先
- search.setAdapter(adapter);//
- mDrawer = (SlidingDrawer) findViewById(R.id.slidingdrawer);
- }
- }
转自: http://gundumw100.iteye.com/blog/1331258
下载: dl.iteye.com/topics/download/bebae969-c880-37a0-9770-3a316438da81
发表评论
-
Android里的音量调节
2013-04-01 13:37 1362步骤1:或许系统音量 ... -
Android Camera 方法分析
2012-03-29 10:52 3525Android Camera源码分析 android通 ... -
MyCameraActivity
2012-03-29 10:10 724package cn.fn; import android. ... -
MyCameraActivity
2012-04-01 13:27 904package cn.fn; import android. ... -
android AutoCompleteTextView+ SQLite
2012-03-21 13:33 1133android AutoCompleteTextView+ S ... -
android 异步回调加载网络图片
2012-03-20 11:50 960在做应用的时候很多时候都会去从网络加载图片,而且还要做各种各样 ... -
ProgressBar+AsyncTask 实现界面数据异步加载
2012-03-20 10:09 1643ProgressBar+AsyncTask 实现界面数据异步 ... -
Android 网络图片异步加载实例
2012-03-20 10:04 1003Android 网络图片异步加载实例 ... -
解决java.lang.OutOfMemoryError
2012-03-19 15:53 1112解决java.lang.OutOfMemoryError ... -
android Text 删除线
2012-03-16 19:35 1195import android.app.Activit ... -
android Gallery 详解
2012-03-14 14:17 1543android Gallery 正文 ... -
Android的线程使用来更新UI----Thread、Handler、Looper、TimerTask,Task,AsynTask等
2012-03-14 11:43 1467Android的线程使用来更新UI----Thread、Han ... -
AsyncTask的使用
2012-03-14 10:59 847AsyncTask的使用 ... -
Android控件开发之Gallery3D效果
2012-03-13 14:38 2950Android控件开发之Gal ... -
android GridView
2012-03-08 10:28 932主类 import android.app.Activi ... -
ListView异步加载图片是非常实用的方法
2012-03-08 10:09 983ListView异步加载图片是非常实用的方法,凡是是要通过网络 ... -
复制assets下的数据库到SD卡
2012-03-07 10:56 1251首先使用sqliteadDev(一个windows下图形化sq ... -
Android异步加载图像小结
2012-03-06 16:46 622Android异步加载图像小结 (1)由于an ... -
android 动态加载List
2012-03-05 11:11 1015main.xml <?xml ver ... -
AutoCompleteTextView
2012-03-02 16:17 1083public class CityAdapter<T& ...
相关推荐
在Android开发中,`AutoCompleteTextView` 是一个非常常见的组件,它用于实现自动补全功能,通常用于输入框中提供用户可能输入的建议。在给定的标题“自定义AutoCompleteTextView下拉列表控件”中,我们可以理解为...
在Android开发中,`AutoCompleteTextView` 是一个非常实用的组件,它允许用户在输入时自动显示匹配的建议列表,通常用于实现搜索框或者输入补全功能。`AutoCompleteTextView` 结合历史记录功能,可以提供更加人性化...
标题与描述均提到了“AutoCompleteTextView 显示更多”,这主要关注于如何优化AutoCompleteTextView在Android应用中的表现,特别是如何调整下拉建议列表的高度,以便在屏幕上显示更多的选项。以下将深入探讨这一主题...
AutoCompleteTextView是Android SDK提供的一种UI组件,用于在用户输入时提供下拉列表的自动提示功能,极大地提升了用户的输入体验。这个控件通常用于搜索框、地址输入等场景,可以根据用户输入的部分字符快速匹配出...
在Android开发中,`AutoCompleteTextView` 是一个非常实用的组件,它允许用户在输入时自动显示匹配的建议列表,从而提升用户体验。本知识点主要关注如何实现`AutoCompleteTextView`与汉字和拼音的关联,使得用户可以...
在Android开发中,`AutoCompleteTextView` 是一个非常实用的组件,它提供了自动补全功能,用户在输入时可以根据预设的数据集得到建议的匹配项。这篇文章将深入探讨`AutoCompleteTextView` 的工作原理以及如何结合...
AutoCompleteTextView是Android SDK提供的一种可以自动补全的文本输入框控件,它结合了EditText和ListView的功能,允许用户在输入时显示出与已输入内容匹配的建议列表。这个功能常见于许多应用程序,如搜索引擎、...
在Android开发中,`AutoCompleteTextView` 是一个非常实用的组件,它提供了自动补全功能,用户在输入时可以接收到下拉列表的建议,提高了输入效率。`MultiAutoCompleteTextView` 是 `AutoCompleteTextView` 的扩展,...
本文将详细介绍如何在Android中仿照百度和谷歌的自动提示功能,利用`AutoCompleteTextView`控件来实现这一功能。 `AutoCompleteTextView`是Android SDK中的一个视图组件,它继承自`EditText`,增加了自动补全的功能...
AutoCompleteTextView是Android SDK提供的一种用于输入文本时自动补全的视图组件,它扩展了EditText,能够根据用户输入的部分文字动态显示出匹配的建议列表。这个功能在许多应用中非常常见,例如搜索引擎、地址...
在Android开发中,`AutoCompleteTextView` 是一个非常实用的组件,它允许用户在输入时自动显示匹配的建议列表,从而提升用户体验。本教程将详细讲解如何利用`AutoCompleteTextView` 实现中文和拼音关联的自动提示...
在Android开发中,`AutoCompleteTextView` 是一个非常实用的组件,它允许用户在输入时自动显示匹配的建议列表。通常,我们使用`ArrayAdapter`来连接数据源和`AutoCompleteTextView`,但有时默认的功能可能无法满足...
在Android开发中,`AutoCompleteTextView` 是一个非常实用的组件,它允许用户在输入时自动显示匹配的建议列表,极大地提高了用户体验。本篇将详细讲解`AutoCompleteTextView`如何用于自动提示联系人信息,并结合从...
在Android开发中,AutoCompleteTextView和TextWatcher是两个非常重要的组件,它们可以帮助我们实现丰富的文本输入交互功能。本文将深入探讨这两个组件,并结合实例展示如何将它们结合起来使用,以实现关键词下拉提示...
在Android开发中,AutoCompleteTextView是一个非常实用的控件,它允许用户在输入时自动显示匹配的建议列表,极大地提高了用户体验。本实例将深入探讨如何使用AutoCompleteTextView,并结合具体的...
AutoCompleteTextView是Android系统提供的一种可以自动补全的文本输入控件,它允许用户在输入时根据已有的数据集匹配并显示建议的选项。这个功能通常用于搜索框、地址输入等场景,提升用户体验。在本主题中,我们将...
AutoCompleteTextView是Android SDK提供的一种视图组件,用于在用户输入文本时提供下拉列表的自动补全功能。它能够极大地提升用户体验,特别是在用户需要从大量预定义选项中选择时。在开发移动应用,尤其是涉及搜索...