这是过滤包含 strings.xml 文本的 ArrayList
的正确方法吗?当我在 SearchView
中输入一些字符时,我在 ListView
中什么也没有得到。
public class SearchActivity extends AppCompatActivity {
private ListView searchList;
private SearchListAdapter searchListAdapter;
private ArrayList<listContents> listArray;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_search);
searchList = (ListView)findViewById(R.id.searchList);
listContents listC[] = new listContents[]{
new listContents(R.string.UtrujjTitle,R.string.UtrujjContent,R.drawable.image1),
new listContents(R.string.AruzzTitle,R.string.AruzzContainer,R.drawable.image2),
new listContents(R.string.ArzTitle,R.string.ArzContainer,R.drawable.image3)
};
listArray = new ArrayList<>(Arrays.asList(listC));
searchListAdapter = new SearchListAdapter(getApplicationContext(),listArray);
searchList.setAdapter(searchListAdapter);
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.search, menu);
final SearchManager searchManager = (SearchManager) getSystemService(Context.SEARCH_SERVICE);
SearchView searchView = (SearchView) menu.findItem(R.id.searchable).getActionView();
searchView.setSearchableInfo(searchManager.getSearchableInfo(getComponentName()));
searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
@Override
public boolean onQueryTextSubmit(String query) {
return false;
}
@Override
public boolean onQueryTextChange(String newText) {
ArrayList<listContents> filtered = new ArrayList<listContents>();
for (int i = 0; i < listArray.size() ; i++){
String title = String.valueOf(listArray.get(i).getTitleList());
String contain = String.valueOf(listArray.get(i).getContentList());
if (title.contains(newText) || contain.contains(newText)){
listContents contents = new listContents(listArray.get(i).getTitleList(),
listArray.get(i).getContentList(),listArray.get(i).getImageList());
filtered.add(contents);
}
searchListAdapter = new SearchListAdapter(getApplicationContext(),filtered);
searchList.setAdapter(searchListAdapter);
}
return false;
}
});
return true;
}
}
适配器类
public class SearchListAdapter extends ArrayAdapter<listContents> {
private Context context;
private listContents[] listContentsList;
private ArrayList<listContents> lister;
public SearchListAdapter(Context context, ArrayList<listContents> list ) {
super(context,0,list);
this.context = context;
this.lister = list;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
listContents listContents = getItem(position);
if (convertView == null) {
convertView = LayoutInflater.from(getContext()).inflate(R.layout.listresults, parent, false);
}
TextView title = (TextView) convertView.findViewById(R.id.listTitle);
title.setText(listContents.getTitleList());
TextView content = (TextView)convertView.findViewById(R.id.listContain);
content.setText(listContents.getContentList());
ImageView imageView = (ImageView)convertView.findViewById(R.id.listImage);
imageView.setImageResource(listContents.getImageList());
return convertView;
}
}
最佳答案
ArrayAdapter
在类中内置了过滤逻辑,因此您实际上不需要在每次进行查询时创建新的适配器,您只需使用查询字符串运行过滤器方法即可。试试这个:
searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
@Override
public boolean onQueryTextSubmit(String query) {
return false;
}
@Override
public boolean onQueryTextChange(String newText) {
searchListAdapter.getFilter().filter(newText);
return true;
}
});
执行比较时,ArrayAdapter
过滤器内部使用类的 toString
值,因此您需要为 重写
,例如像这样的事情:toString
>listContents
@Override
public String toString() {
return getTitleList() + " - " + getContentList();
}
编辑:
我注意到您将资源 ID 而不是实际字符串传递给 listContents
类。 R.string.UtrujjTitle
之类的值只是整数,它们是实际字符串的标识符。
假设 getTitleList()
没有返回实际的字符串,而只是返回资源 id,那么上面的 toString
方法将不起作用。无论您采用哪种过滤方法,您都需要从资源 ID 中获取实际的字符串来进行比较。
那么,您可以选择更改代码以将实际字符串存储在 listContents
中,而不是资源 ID,或者传入 Context
引用。
通过 Context
引用,您可以对 toString()
进行以下更改:
@Override
public String toString() {
return context.getString(getTitleList()) + " - " + context.getString(getContentList());
}
编辑2:
查看您的过滤代码,该错误很可能是由以下两行引起的:
String title = String.valueOf(listArray.get(i).getTitleList());
String contain = String.valueOf(listArray.get(i).getContentList());
相反,您可能想要做的事情(假设 getter 返回资源 ID)是:
String title = getString(listArray.get(i).getTitleList());
String contain = getString(listArray.get(i).getContentList());
但是,在使用适配器的过滤功能时,重新实例化适配器比重复使用同一适配器可能会产生更多开销。但如果您想保留已有的内容,此更改可能会解决问题。
关于java - 带有 searchView 的 ArrayList 过滤器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36698185/