我开发了 Android 应用(最小API 8 ,最高API 20 ),其中列出了 assets文件夹中的所有文件,并使用 ArrayAdapter 将其显示为列表。当用户选择任何项目时,文件将根据项目位置打开并显示在下一个活动中。 我正在尝试向列表添加搜索功能,因此当用户键入搜索查询时,列表会被过滤。我确实尝试将 TextChangedListener 添加到Activity中,但是您知道它有限制,仅适用于单个字(添加空格会使列表空白)。在过去的几天里,我已经检查了stacoverflow中有关此问题的所有问题和答案,但无法解决我的问题。
有没有办法覆盖 getFilter 方法,将搜索功能添加到接受任意数量字词并过滤列表的列表中?
或
而不是使用TextChangeListener添加 SearchView 来归档此目标?
这是java代码:
import java.io.IOException;
import java.util.ArrayList;
import android.app.ListActivity;
import android.content.Intent;
import android.content.res.AssetManager;
import android.os.Bundle;
import android.text.Editable;
import android.text.TextWatcher;
import android.view.View;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ListView;
public class All extends ListActivity implements View.OnClickListener{
String[] items;
ListView l;
EditText etSearch;
Button btnProgramsList, btnMainMenu;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.list);
btnProgramsList = (Button) findViewById(R.id.btnProgramsList);
btnMainMenu = (Button) findViewById(R.id.btnMainMenu);
btnProgramsList.setOnClickListener(this);
btnMainMenu.setOnClickListener(this);
getFileList();
l = getListView();
final ArrayAdapter<String> adapter = new ArrayAdapter<String>(All.this, android.R.layout.simple_list_item_1, items);
l.setAdapter(adapter);
etSearch = (EditText) findViewById(R.id.etSearch);
etSearch.addTextChangedListener(new TextWatcher() {
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
adapter.getFilter().filter(s);
}
@Override
public void beforeTextChanged(CharSequence s, int start, int count,
int after) {
}
@Override
public void afterTextChanged(Editable s) {
}
});
}
private void getFileList() {
ArrayList<String> filesArrayList = new ArrayList<String>();
final AssetManager assetManager = getAssets();
String[] filelist;
try {
filelist = assetManager.list("All");
for(String name: filelist){
name = name.substring(0, name.length() - 2);
filesArrayList.add(name);
}
} catch (IOException e) {
e.printStackTrace();
}
items = new String[filesArrayList.size()];
filesArrayList.toArray(items);
}
@Override
protected void onListItemClick(ListView l, View v, int position, long id) {
super.onListItemClick(l, v, position, id);
int p = position;
Intent i = new Intent(All.this, AllPrograms.class);
i.putExtra("KEY", p);
startActivity(i);
}
@Override
public void onClick(View v) {
if(v.getId() == R.id.btnMainMenu){
Intent i = new Intent(".MainMenu");
startActivity(i);
}
else{
Intent i = new Intent(".Menu");
startActivity(i);
}
}
}
答案 0 :(得分:0)
答案 1 :(得分:0)
感谢 Sam (https://stackoverflow.com/a/13391689/4226207),问题已解决。
我刚刚在我的应用中创建了一个新类 ArrayAdapter.java 并覆盖了 getFilter()方法,只是下面的部分 performFiltering()。然后我删除了
import android.widget.ArrayAdapter;
现在搜索是完美的。这是我在ArrayAdapter类中更改的部分:
@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) {
ArrayList<T> list;
synchronized (mLock) {
list = new ArrayList<T>(mOriginalValues);
}
results.values = list;
results.count = list.size();
} else {
String prefixString = prefix.toString().toLowerCase();
ArrayList<T> values;
synchronized (mLock) {
values = new ArrayList<T>(mOriginalValues);
}
final int count = values.size();
final ArrayList<T> newValues = new ArrayList<T>();
for (int i = 0; i < count; i++) {
final T value = values.get(i);
final String valueText = value.toString().toLowerCase();
// First match against the whole, non-splitted value
if (valueText.startsWith(prefixString)) {
newValues.add(value);
} else {
final String[] prefixes = prefixString.split(" ");
final int prefixCount = prefixes.length;
int loc;
if(valueText.startsWith(prefixes[0]) || (loc = valueText.indexOf(' ' + prefixes[0])) > -1)
loc = valueText.indexOf(prefixes[0]);
for (int j = 1; j < prefixCount && loc > -1; j++)
loc = valueText.indexOf(' ' + prefixes[j], loc + 2);
if(loc > -1)
newValues.add(value);
}
}
results.values = newValues;
results.count = newValues.size();
}
return results;
}