ListView过滤器正确过滤但显示错误的结果

Wil*_*lis 4 java android android-listview android-adapter searchview

我有一个自定义Adapter,我用来显示自定义对象ListView.此外,我使用了一个SearchView允许我搜索ListView并过滤掉结果的.但是,当我尝试输入搜索时,我注意到了一些奇怪的行为.只要我搜索列表中的项目,项目就会显示在过滤器中 - 但是,项目始终显示在列表顶部.如果列表中有10个项目,并且搜索产生5个匹配项,则结果将显示列表中的前5个项目而不是5个实际匹配项目.例如,考虑一下这个列表上有6个摩托车头盔:

  • 图标
  • 哈雷戴维森
  • 乔火箭队
  • 秀爱
  • 雷神

如果我搜索"ho",结果列表应如下所示:

  • S ho ei
  • T ho r

但是,我得到的列表是前两项:

  • 图标

我无法弄清楚搜索无法正常工作的原因.任何帮助,将不胜感激.我的代码如下所示......

HelmetActivity.java

public class HelmetActivity extends ActionBarActivity implements
        SearchView.OnQueryTextListener{

    private Menu menu;
    private ListView listView;
    private HelmetAdapter helmetAdapter;
    private List<Helmet> arrayList;
    private SearchManager searchManager;
    private SearchView searchView;
    private MenuItem searchMenuItem;

    @Override
    protected void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.helmet_activity);
        ActionBar actionBar = getSupportActionBar();
        actionBar.setElevation(0);
        listView = (ListView) findViewById(R.id.helmet_listview);
        listView.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE);
        arrayList = new ArrayList<Helmet>();
        listView.setLongClickable(true);
        helmetAdapter = new HelmetAdapter(this, R.layout.helmet, arrayList);
        listView.setAdapter(helmetAdapter);

        arrayList.add(new Helmet("Bell"));
        arrayList.add(new Helmet("Icon"));
        arrayList.add(new Helmet("Harley Davidson"));
        arrayList.add(new Helmet("Joe Rocket"));
        arrayList.add(new Helmet("Shoei"));
        arrayList.add(new Helmet("Thor"));
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu)
    {
        this.menu = menu;
        MenuInflater menuInflater = getMenuInflater();
        menuInflater.inflate(R.menu.helmet_activity_menu, menu);
        SearchManager searchManager = (SearchManager) getSystemService(
                Context.SEARCH_SERVICE);
        searchMenuItem = menu.findItem(R.id.action_search);
        searchView = (SearchView) searchMenuItem.getActionView();
        searchView.setSearchableInfo(searchManager.getSearchableInfo(
                getComponentName()));
        searchView.setSubmitButtonEnabled(true);
        searchView.setOnQueryTextListener(HelmetActivity.this);

        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item)
    {
        return super.onOptionsItemSelected(item);
    }

    @Override
    public boolean onQueryTextSubmit(String query) {
        return false;
    }

    @Override
    public boolean onQueryTextChange(String newText)
    {
        helmetAdapter.getFilter().filter(newText);

        return true;
    }
}
Run Code Online (Sandbox Code Playgroud)

HelmetAdapter.java

public class HelmetAdapter extends ArrayAdapter<Helmet> implements Filterable
{
    private int resource;
    private LayoutInflater inflater;
    private Context context;
    private List<Helmet> helmetList;
    private List<Helmet> filteredHelmetList;
    private HelmetFilter helmetFilter;

    public HelmetAdapter (Context pContext, int pResource, List<Helmet> helmetList)
    {
        super (pContext, pResource, helmetList);
        resource = pResource;
        inflater = LayoutInflater.from (pContext);
        context = pContext;
        this.helmetList = helmetList;
        this.filteredHelmetList = helmetList;
        getFilter();
    }

    @Override
    public View getView (final int position, View convertView, ViewGroup parent)
    {

        if (convertView == null)
        { convertView = inflater.inflate(resource, parent, false); }

        String uri;
        int imageResource;
        Drawable image;
        Helmet helmet = getItem (position);
        TextView hName = (TextView) convertView.findViewById(R.id.h_name);
        hName.setText(helmet.getName());

        return convertView;
    }

    @Override
    public int getCount()
    { return filteredHelmetList.size(); }

    @Override
    public Filter getFilter()
    {
        if (helmetFilter == null)
        {
            helmetFilter = new HelmetFilter();
        }

        return helmetFilter;
    }

    private class HelmetFilter extends Filter
    {
        @Override
        protected FilterResults performFiltering (CharSequence constraint)
        {
            FilterResults filterResults = new FilterResults();
            if (constraint != null && constraint.length() > 0)
            {
                ArrayList<Helmet> temporaryHelmetList = new ArrayList<Helmet>();
                for (Helmet helmet : helmetList)
                {
                    if (helmet.getName().toLowerCase().contains(constraint.toString()
                            .toLowerCase()))
                    {
                        temporaryHelmetList.add(helmet);
                    }
                }
                filterResults.count = temporaryHelmetList.size();
                filterResults.values = temporaryHelmetList;
            }
            else
            {
                filterResults.count = helmetList.size();
                filterResults.values = helmetList;
            }
            return filterResults;
        }

        @SuppressWarnings("unchecked")
        @Override
        protected void publishResults(CharSequence constraint, FilterResults results)
        {
            filteredHelmetList = (ArrayList<Helmet>) results.values;
            notifyDataSetChanged();
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

Helmet.java

public class Helmet
{

    public Helmet (String name)
    {
        super();
        this.name = name;
    }

    private String     name;

    public String getName ()
    {
        return name;
    }

    public void setName (String pName)
    {
        this.name = pName;
    }
}
Run Code Online (Sandbox Code Playgroud)

bwe*_*egs 6

在我看来,你的问题很可能在于getView(..)适配器的方法.

这条线特别 -

Helmet helmet = getItem (position);
Run Code Online (Sandbox Code Playgroud)

如果您在原始头盔阵列中返回该项目,那么这将解释您获得结果的原因.但是,我无法确定,因为我没有getItem(..)在您的代码中看到您的方法.如果情况确实如此,那么您当然希望在此处返回过滤结果(如果有的话)而不是未过滤列表中的结果.

  • 我最终修改了我的`getItem`和`getView`方法,现在它可以工作了.谢谢你指点我正确的方向. (2认同)