java - 带有 searchView 的 ArrayList 过滤器

标签 java android arraylist

这是过滤包含 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/

相关文章:

java - 是否有可能在 Intellij 的单独选项卡/部分中打开一段代码?

Android 系统颜色常数

android - SQLite 清除缓存后从 Assets 中读取 base

java - 将字符串添加到存储在 ArrayList 中的 String ArrayList

java - 为什么 Java ArrayList 删除功能似乎花费这么少?

java - 使用 Java 的 BitTorrent 协议(protocol) - 成功握手后的位字段

java - 我应该使用微服务或映射实体在多个应用程序之间共享数据吗?

java - Spring 启动 : "No qualifying bean of type... found" when autowiring concrete class

java - Android ZXing 解码图像后等待时间

java - 如何将 Arraylist Lat Long 值添加到新的 LatLng 类中