2014-08-27 39 views
0

我有一个简单的问题:列表视图自动完成

我有一个ListView数据与这些字符串:

String words[] = { 
     "man", 
     "guy", 
     "penny-wise", 
     "(just)", 

我增加了一个搜索funciontality到列表视图,就像这样:

  * Enabling Search Filter 
    * */ 
    search.addTextChangedListener(new TextWatcher() { 

     @Override 
     public void onTextChanged(CharSequence cs, int arg1, int arg2, int arg3) { 
      // When user changed the Text 
      Words.this.adapter.getFilter().filter(cs); { 

       lv.setOnItemClickListener(new OnItemClickListener(){ 

        public void onItemClick(AdapterView<?> arg0, View arg1, int arg2, 
        long arg3) { 




        } 

       }); 

      } 


     } 

     @Override 
     public void beforeTextChanged(CharSequence arg0, int arg1, int arg2, 
       int arg3) { 
      // TODO Auto-generated method stub 

     } 

     @Override 
     public void afterTextChanged(Editable arg0) { 
      // TODO Auto-generated method stub       
     } 




    }); 
} 

所以,搜索功能运作良好,但是我希望能够识别出当我从字符串(列表视图数据)中输入角色的一部分作为明智的项目中的“明智”时,他们不会提供便士作为建议它应该是(因为它是在列表视图数据存在)

如果我只输入他们不提供的建议...因为有()在我的字符串...

哪有我解决此问题。我是新手。谢谢!!!

+0

那么你的'搜索'的东西是一个AutoCompleteTextView? – reVerse 2014-08-27 15:13:12

回答

2

您需要为适配器创建您自己的自定义过滤器。为了做到这一点,您需要创建自己的自定义适配器类。这不是一件容易的事,尤其是考虑到你是一个新手。

您没有提及您使用的是哪种类型的适配器。如果它是一个ArrayAdapter,那么最好的和最简单的解决方案就是使用开放源码库Advanced-Adapters。它有一个等效的适配器,可以轻松地让您自定义过滤逻辑,但是您需要手动处理视图创建。你可以阅读更多关于here

否则,很多人会告诉你直接扩展ArrayAdapter类并覆盖getFilter()方法,但这是不正确的答案。为什么?多种原因。

过滤操作发生在后台线程上。这意味着你需要担心并发问题。这提出了一些问题。首先,ArrayAdapter使用的锁没有公开,也没有使用类实例的锁。这意味着你需要你自己的锁,这会大大增加死锁的风险......对同一组数据有两个不同的锁是很糟糕的,特别是因为ArrayAdapter在更多地方同步,然后只是过滤器。

ArrayAdapter使用两个列表来跟踪它的数据:mObjects和。前者跟踪显示的列表,后者跟踪整个列表以查看过滤器操作发生的时间。例如,如果过滤10个项目的列表以仅显示1,那么适配器在内部仍然需要知道最初的10个用于稍后恢复列表的内容。当覆盖getFilter()时,您必须提供类似的行为,但有一个主要问题。 ArrayAdapter不公开任何列表。虽然您可以一次从mObjects中提取项目,但无法拉取整个列表本身。一个常见的解决方案是在用项目实例化自定义适配器时创建另一个列表。

但是,由于在适配器中添加/删除/更新项目的方式多种多样,因此会出现更多问题。这意味着您需要重写每个mutate方法以确保您的列表与ArrayAdapter保持同步。添加一个事实,即您必须考虑适配器是否进一步被过滤会使事情复杂化。基本上你的列表可以很容易地从内部的ArrayAdapter中失去同步。

到此为止,您已经覆盖了很多ArrayAdapter的方法,它使得ArrayAdapter在很大程度上无关紧要。在开始跟踪派生自ArrayAdapter的自定义类中的数据列表的那一刻,您应该停下来并从头开始实施自己的适配器。

这就是为什么从BaseAdapter创建您自己的适配器是最好的解决方案。如果你知道自己在做什么,那么做起来并不难......真的很痛苦。否则,该开放源代码库将为您完成所有这些工作,同时保留getView()方法摘要并提供一种自定义过滤器逻辑的方法。

+0

你介意告诉我们为什么重写'getFilter()'方法会是一个不正确的答案? – reVerse 2014-08-27 15:36:46

+0

更新答案与原因。 – 2014-08-27 17:31:50

+0

感谢您的详细解释,但我不得不承认,我从来没有遇到过使用'getFilter()'方法的问题。 (好吧,我几乎做了你刚刚说的所有事情,即创建第二个列表,处理并发性等等) – reVerse 2014-08-27 17:51:48