java - ListView Filter 过滤正确但显示错误结果

标签 java android android-listview android-adapter searchview

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

  • 贝尔
  • 图标
  • 哈雷戴维森
  • 乔火箭
  • 翔荣
  • 雷神

如果我搜索“ho”,结果列表应该如下:

  • Shoei
  • Thor

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

  • 贝尔
  • 图标

我不明白为什么搜索不能正常工作。任何帮助,将不胜感激。我的代码如下所示...

Helm Activity .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;
    }
}

Helm 适配器.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();
        }
    }
}

Helm .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;
    }
}

最佳答案

在我看来,您的问题很可能出在适配器的 getView(..) 方法上。

特别是这一行-

Helmet helmet = getItem (position);

如果您要退回原始 Helm 阵列中的元素,那么这就可以解释为什么您会得到这样的结果。但是,我不能确定,因为我没有在您的代码中看到您的 getItem(..) 方法。如果情况确实如此,那么您当然希望在此处返回过滤后的结果(如果有的话),而不是未过滤列表中的结果。

关于java - ListView Filter 过滤正确但显示错误结果,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28259304/

相关文章:

Java 服务器和客户端在本地工作,但不通过 IP

java - 在 Java 中使用列表来存储用户输入并执行任务

android - Cocos2d-x 项目中的宏

android - Cordova 没有使用最新的 Android System Webview

android - 无尽的ListView

java - 带别名的 HQL 查询

Java - requestFocus当前元素

php - Android 应用程序未获得 JSON 响应

java - 如何使用findViewById获取ListView

android - 如何处理 ListView 中的快速连续点击