在Android上,我如何ListView
根据用户输入进行过滤,其中显示的项目是根据TextView
值动态更新的?
我正在寻找这样的东西:
------------------------- | Text View | ------------------------- | List item | | List item | | List item | | List item | | | | | | | | | -------------------------
Hamy.. 286
首先,您需要创建一个包含EditText和ListView的XML布局.
这将使一切正常,在ListView上方有一个很好的EditText.接下来,像平常一样创建ListActivity,但setContentView()
在onCreate()
方法中添加一个调用,以便我们使用最近声明的布局.请记住,我们ListView
特意识别了android:id="@android:id/list"
.这允许我们ListActivity
知道ListView
在声明的布局中使用哪个.
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.filterable_listview); setListAdapter(new ArrayAdapter(this, android.R.layout.simple_list_item_1, getStringArrayList()); }
现在运行应用程序应该显示您的上一个ListView
,上面有一个很好的框.为了使该框执行某些操作,我们需要从中获取输入,并使该输入过滤列表.虽然很多人都尝试手动执行此操作,但大多数 ListView
Adapter
类都附带了一个Filter
可用于自动执行过滤的对象.我们只需将输入管道输入EditText
到Filter
.事实证明这很容易.要运行快速测试,请将此行添加到您的onCreate()
通话中
adapter.getFilter().filter(s);
请注意,您需要将您保存ListAdapter
到变量才能使其正常工作 - 我已将我ArrayAdapter
之前保存到名为'adapter'的变量中.
下一步是从中获取输入EditText
.这实际上需要一些思考.你可以添加OnKeyListener()
到您的EditText
.但是,此侦听器仅接收一些关键事件.例如,如果用户输入"wyw",预测文本可能会推荐"眼睛".在用户选择"wyw"或"eye"之前,您OnKeyListener
将不会收到关键事件.有些人可能更喜欢这种解决方案,但我发现它令人沮丧.我想要每个关键事件,所以我可以选择过滤或不过滤.解决方案是TextWatcher
.只需创建并添加TextWatcher
到EditText
,并通过ListAdapter
Filter
每一次的过滤器请求文本更改.记得删除TextWatcher
in OnDestroy()
!这是最终的解决方案:
private EditText filterText = null; ArrayAdapteradapter = null; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.filterable_listview); filterText = (EditText) findViewById(R.id.search_box); filterText.addTextChangedListener(filterTextWatcher); setListAdapter(new ArrayAdapter (this, android.R.layout.simple_list_item_1, getStringArrayList()); } private TextWatcher filterTextWatcher = new TextWatcher() { public void afterTextChanged(Editable s) { } public void beforeTextChanged(CharSequence s, int start, int count, int after) { } public void onTextChanged(CharSequence s, int start, int before, int count) { adapter.getFilter().filter(s); } }; @Override protected void onDestroy() { super.onDestroy(); filterText.removeTextChangedListener(filterTextWatcher); }
Viktor - 如果你感兴趣的单词用空格分隔,那么它会自动完成.否则,不是真的.可能最简单的方法是通过扩展它来继承Adapter,并覆盖getFilter方法以返回您定义的Filter对象.请参阅http://github.com/android/platform_frameworks_base/blob/master/core/java/android/widget/ArrayAdapter.java#L449以了解默认ArrayFilter的工作原理 - 复制95%的此代码和改变第479和486行 (12认同)
是否有任何直接的方式来过滤"包含"中的ListView而不是像这个解决方案那样的"开头"时尚? (7认同)
这真的有必要吗?>记得在OnDestroy()中删除TextWatcher (4认同)
哈米,优秀的写作!我有一个问题:我已经实现了这个,在我输入的每个字母之后,ListView消失了几秒钟然后又回来了,过滤了.你有没有经历过这个?我的直觉是因为我在列表中有600多个项目,具有非平凡的toString()函数. (2认同)
在较小屏幕上的横向模式下,EditText +键盘占据整个屏幕,并且ListView不可见!有解决方案吗 (2认同)
j7nn7k.. 10
运行程序将导致力关闭.
我划过界限:
机器人:ID = "@ + building_list/search_box"
同
机器人:ID = "@ + ID/search_box"
这可能是问题吗?什么是'@ + building_list'?
首先,您需要创建一个包含EditText和ListView的XML布局.
这将使一切正常,在ListView上方有一个很好的EditText.接下来,像平常一样创建ListActivity,但setContentView()
在onCreate()
方法中添加一个调用,以便我们使用最近声明的布局.请记住,我们ListView
特意识别了android:id="@android:id/list"
.这允许我们ListActivity
知道ListView
在声明的布局中使用哪个.
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.filterable_listview); setListAdapter(new ArrayAdapter(this, android.R.layout.simple_list_item_1, getStringArrayList()); }
现在运行应用程序应该显示您的上一个ListView
,上面有一个很好的框.为了使该框执行某些操作,我们需要从中获取输入,并使该输入过滤列表.虽然很多人都尝试手动执行此操作,但大多数 ListView
Adapter
类都附带了一个Filter
可用于自动执行过滤的对象.我们只需将输入管道输入EditText
到Filter
.事实证明这很容易.要运行快速测试,请将此行添加到您的onCreate()
通话中
adapter.getFilter().filter(s);
请注意,您需要将您保存ListAdapter
到变量才能使其正常工作 - 我已将我ArrayAdapter
之前保存到名为'adapter'的变量中.
下一步是从中获取输入EditText
.这实际上需要一些思考.你可以添加OnKeyListener()
到您的EditText
.但是,此侦听器仅接收一些关键事件.例如,如果用户输入"wyw",预测文本可能会推荐"眼睛".在用户选择"wyw"或"eye"之前,您OnKeyListener
将不会收到关键事件.有些人可能更喜欢这种解决方案,但我发现它令人沮丧.我想要每个关键事件,所以我可以选择过滤或不过滤.解决方案是TextWatcher
.只需创建并添加TextWatcher
到EditText
,并通过ListAdapter
Filter
每一次的过滤器请求文本更改.记得删除TextWatcher
in OnDestroy()
!这是最终的解决方案:
private EditText filterText = null; ArrayAdapteradapter = null; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.filterable_listview); filterText = (EditText) findViewById(R.id.search_box); filterText.addTextChangedListener(filterTextWatcher); setListAdapter(new ArrayAdapter (this, android.R.layout.simple_list_item_1, getStringArrayList()); } private TextWatcher filterTextWatcher = new TextWatcher() { public void afterTextChanged(Editable s) { } public void beforeTextChanged(CharSequence s, int start, int count, int after) { } public void onTextChanged(CharSequence s, int start, int before, int count) { adapter.getFilter().filter(s); } }; @Override protected void onDestroy() { super.onDestroy(); filterText.removeTextChangedListener(filterTextWatcher); }
运行程序将导致力关闭.
我划过界限:
机器人:ID = "@ + building_list/search_box"
同
机器人:ID = "@ + ID/search_box"
这可能是问题吗?什么是'@ + building_list'?