带有searchView的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值,因此您需要为listContents重写toString,例如:

@Override
public String toString() {
    return getTitleList() + " - " + getContentList();
}


编辑:我注意到您将资源id而不是实际字符串传递给listContents类。诸如R.string.UtrujjTitle之类的值只是整数,它们是实际字符串的标识符。

假设getTitleList()没有返回实际的字符串,而只是返回资源id,那么上面的toString方法将不起作用。无论采用哪种过滤方法,都需要从资源id中获取实际字符串来进行比较。

那么,您可以选择更改代码,将实际的String存储在listContents中,而不是资源id中,或者传入Context引用。

使用Context引用,可以对toString():进行以下更改

@Override
public String toString() {
    return context.getString(getTitleList()) + " - " + context.getString(getContentList());
}


编辑2:查看您的过滤代码,错误很可能是由以下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());

然而,在使用过滤器功能的同时,重新实例化适配器比重用同一个适配器可能会有更多的开销。但是,如果你想保留你已经拥有的,这个改变可能会解决它。

此处,

ArrayList channelData=新的ArrayList<gt;();ArrayList filtered_channelData=新的ArrayList<gt;();

edt_search_channel.addTextChangedListener(新TextWatcher(){@Overridepublic void beforeTextChanged(CharSequence CharSequence,int i,int i1,int i2){}

        @Override
        public void onTextChanged(CharSequence charSequence, int start, int before, int count) {
            if (filtered_channelData != null) {
                filtered_channelData.clear();
                Log.d("mytag", "list is clear" + filtered_channelData.size());
            }
            for (int i = 0; i < channelData.size(); i++) {
                if (channelData.get(i).getName().toLowerCase().trim()
                        .contains(edt_search_channel.getText().toString().toLowerCase().trim())) {
                    filtered_channelData.add(channelData.get(i));
                    HashSet hs = new HashSet();
                    hs.addAll(filtered_channelData);
                    filtered_channelData.clear();
                    filtered_channelData.addAll(hs);
                }
            }
            channelAdapter = new ChannelAdapter(context, filtered_channelData, dialogChannel);
            rv_channel.setAdapter(channelAdapter);
            Log.d("mytag", "filtered_skill_listing size in out of for loop" + filtered_channelData.size());
            channelAdapter.notifyDataSetChanged();
        }
        @Override
        public void afterTextChanged(Editable editable) {
            if (edt_search_channel.getText().toString().equals("")) {
                channelAdapter = new ChannelAdapter(context, channelData, dialogChannel);
                rv_channel.setAdapter(channelAdapter);
                channelAdapter.notifyDataSetChanged();
            }
        }
    });

最新更新