2011-03-31 77 views
3

作为标题,如何删除由AutoCompleteTextView使用的ArrayAdapter上的过滤以获取原始列表?如何删除AutoCompleteTextView中使用的ArrayAdapter上的筛选器?

多一点背景:

这一切都来自可悲的事实是,在传递给onItemClick()的“位置”值是没用的开始。 “位置”是指阵列过滤后的位置,但我需要知道它的实际位置。所以,我试图做的是当我得到所选项目的文本(通过使用getItemAtPosition(position)),我将它与支持ArrayAdapter的原始字符串数组逐一比较。但是,我发现当调用onItemClick()时,适配器已经过滤,我不再有权访问原始数组。所以我想如果我可以删除过滤器,也许我可以找回原始数组并查找其中的选定项目。

ArrayAdapter<String> mAdapter; 

public void onCreate() { 

    // Create an adapter and remembere it as a class member. 
    mAdapter = new ArrayAdapter<String>(this, layoutId); 

    // Add 100 strings to it and attach it to an AutoCompleteTextView 
    for (int i = 0; i < 100; i++) 
     mAdapter.add("random text"); 
    ((AutoCompleteTextView)findViewById(id)).setAdapter(mAdapter); 
} 

@Override 
public void onItemClick(AdapterView<?> actv, View view, int position, long id) { 

    if (actv.getAdapter().equals(mAdapter)) 
     Log.d("The adapter contained in actv is the same one I created earlier."); 

    // And, I can get the text of the item the user selected 

    String selected = (String)actv.getItemAtPosition(position); 

    // However, although the adapter passed in is still the same one, but the 
    // number of items in it is only 1! Because the array has been filtered. 

    int numItems = actv.getAdapter.getCount(); 

    // So, I'm thinking if I can somehow remove the filtering here, then I can 
    // get back those 100 items, and do a search like following: 

    for (int i = 0; i < actv.getAdapter.getCount(); i++) 
     if (selected == actv.getAdapter.getItem(i)) 
      break; // Eureka!!! 
} 

要解决获得所选项目的实际位置的问题:

  1. 是否有利用“ID”值的方法吗?比如,为每个项目分配一个id,然后希望onItemClick()会传回正确的id。

  2. 就像我上面说过的,删除过滤器(有可能),取回原来的100个项目,并执行一个一个的搜索。

  3. 这是最后的手段,我知道它会起作用,但我不想这样做:一旦我得到所选文本的文本,我就会回到数据源(从一个数据库),查询这100个项目,并执行搜索。

  4. 另一个跛脚最后一招:要避免的开销上再次访问该数据库在#3,当的onCreate(),同时创造一个ArrayAdapter,我用我自己的一个ArrayList记住所有那些100个字符串。

我是不是全都做错了?从AutoCompleteTextView获取所选项目的真实位置的“正确”方式是什么?

非常感谢!

(我读的地方,一些团购似乎是来自谷歌Android团队说,应该使用getFirstVisiblePosition()来解决的位置,但我想不出如何。)

+0

我正在做类似的事情! http://stackoverflow.com/questions/12854336/autocompletetextview-backed-by-cursorloader – toobsco42 2012-10-30 19:47:14

回答

0

这实际上是很容易解决..而不是每个元素添加到适配器,因为你得到它(我假设你的随机文本部分只是为了举例的目的),而是使用以下代码:

首先建立你的数组到一个变量,称之为myArray .. 然后像这样初始化您的适配器:

mAdapter = new ArrayAdapter<String>(this, layoutId, myArray); 

现在确保myArray是一个类变量,所以你可以从类中的任何其他地方引用它。当然,如果你需要从另一个类访问它,你想为它创建一个getter ...然后您可以轻松遍历数组以查看所选值是否在数组中。您将拥有整组数据,而不是尝试从适配器中获取。

下面是使用验证的容貌相似,用例一个很好的例子: Android, Autocomplettextview, force text to be from the entry list

+0

我觉得我说得有点太快..我很困惑,为什么你会添加每个元素到适配器(它在内部创建自己的数据结构,但你不愿意创建自己的数据结构来存储数据)......如果你真的担心资源,你应该使用CursorAdaptor(如果数据来自数据库)。还要注意,在示例I发送给您数组已排序,您可以执行二进制搜索以检查值是否在数组中 - O(log n)而不是O(n)。 – 2011-05-05 05:16:52

0

就我而言,我的地址可以通过自动填充或点击地图进行设置。如果用户点击地图,则应将editText文本设置为从地图中选择的地址,在这种情况下,应暂时禁用过滤。

我这样的代码:

public void OnAddressFound(String address) { 
       // Temporary disable autocomplete 
       editTextSearch.setAdapter(null); 
       editTextSearch.setText(address); 
       // Enable autocomplete again 
       setAutoCompleteAdapter(); 
      } 

其中setAutoCompleteAdapter()时的onCreate过程中暂时禁用调用,并再次/启用过滤器:

void setAutoCompleteAdapter() { 
    PlacesAutoCompleteAdapter adapter = new PlacesAutoCompleteAdapter(this, R.layout.item_autocomplete_map_search, autoCompleteList); 
    editTextSearch.setAdapter(adapter); 
    adapter.notifyDataSetChanged(); 
} 

希望其对您有帮助也。

相关问题