【问题标题】:Filtering on a list筛选列表
【发布时间】:2015-10-21 09:51:21
【问题描述】:

我有一个国家/地区列表,我将其用作搜索,因此如果我正在搜索特定国家/地区,一旦找到我想要的国家/地区,我就会从过滤列表中选择它。问题是,当我选择过滤列表中的第 112 项时,如果它在过滤列表的顶部,结果实际上是未过滤列表中的第 1 项。

这将是一个更简单的解释方式,我已经上传了一个视频,可以在这里找到Search Example

我的搜索适配器在这里:

    public Context mContext;
public ArrayList<Countries> countryArrayList;
public ArrayList<Countries> original;

public CountryAdapter(Context context, ArrayList<Countries> countryArrayList) {
    mContext = context;
    this.countryArrayList = countryArrayList;
}

@Override
public void notifyDataSetChanged() {
    super.notifyDataSetChanged();
}

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

@Override
public Object getItem(int position) {
    return countryArrayList.get(position);
}

@Override
public long getItemId(int position) {
    return position;
}

@Override
public View getView(int position, View convertView, ViewGroup parent) {
    CountryHolder holder;

    if (convertView == null) {
        convertView = LayoutInflater.from(mContext).inflate(R.layout.search_results_row_list, parent, false);
        holder = new CountryHolder();
        holder.countryName = (TextView) convertView.findViewById(R.id.country_text);
        holder.countryFlag = (ImageView) convertView.findViewById(R.id.country_flag);
        convertView.setTag(holder);
    } else {
        holder = (CountryHolder) convertView.getTag();
    }
    holder.countryName.setText(countryArrayList.get(position).getCountryName());
//        holder.countryFlag.setImageResource(countryArrayList.get(position).getImgId());
    return convertView;
}

@Override
public Filter getFilter() {
    return new Filter() {
        @Override
        protected FilterResults performFiltering(CharSequence constraint) {
            final FilterResults oReturn = new FilterResults();
            final ArrayList<Countries> results = new ArrayList<>();
            if (original == null)
                original = countryArrayList;
            if (constraint != null) {
                if (original != null && original.size() > 0) {
                    for (final Countries g : original) {
                        if (g.getCountryName()
                                .contains(constraint.toString()))
                            results.add(g);
                    }
                }
                oReturn.values = results;
            }
            return oReturn;
        }

        @SuppressWarnings("unchecked")
        @Override
        protected void publishResults(CharSequence constraint, FilterResults results) {
            countryArrayList = (ArrayList<Countries>) results.values;
            notifyDataSetChanged();
        }
    };
}

public class CountryHolder {
    TextView countryName;
    ImageView countryFlag;
}

抱歉,我忘记了我实际选择的国家/地区

private void setSearchResultsList() {
    final CountryAdapter countryAdapter = new CountryAdapter(getActivity(), controller.getCountriesArrayList());
    countryAdapter.getFilter().filter(searchPhrase);
    countryAdapter.notifyDataSetChanged();

    listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
        @Override
        public void onItemClick(AdapterView<?> parent, View view, int position, long id) {


            String selectedCountry = controller.getCountriesArrayList().get(+position).getCountryName();
            mISearch.searchResult(selectedCountry);

        }
    });

    listView.setAdapter(countryAdapter);
}

谢谢

【问题讨论】:

  • 错误很明显,并且不在此代码中...但在 onItemClick ...显然您正在使用位置从原始数组列表中获取项目...但这是错误的方式...正常方法有据可查...

标签: java android


【解决方案1】:

永远一次: 如果您使用的是AdapterView.setOnItemClickListener,那么获得点击项的正确方法是这样的实现:

adapterView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
    @Override
    public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
        Object item = parent.getItemAtPosition(position);
    }
});

parent.getItemAtPosition(position)AdapterView 中使用的适配器返回Adapter.getItem(position)(带有setAdapter

例如:

  • 如果您使用的是ArrayAdapter&lt;T&gt;,您应该将parent.getItemAtPosition(position) 转换为T 并使用它...

  • ArrayAdapter&lt;POJO&gt; 使用:

    POJO item = (POJO)parent.getItemAtPosition(position);

  • 如果您使用的是CursorAdapter

    • Cursor c = (Cursor)parent.getItemAtPosition(position);
  • 如果您使用的是SimpleAdapter

    • Map&lt;String, ?&gt; item = ( Map&lt;String, ?&gt;)parent.getItemAtPosition(position);

当然,这取决于您的 Adapter 实现...所以您应该记住 Adapter 应该使用 getItem(position) 返回正确的对象

如文档中所述,它适用于:ListViewGridViewSpinnerGalleryAdapterView 的其他子类

所以在你的情况下,正确的方法显然是:

Countries country = (Countries)parent.getItemAtPosition(position);

【讨论】:

  • 感谢 Selvin,感谢!我试过了,这也能产生奇迹。这似乎也是2的更好答案
【解决方案2】:

这样做


adapter类中添加一个方法来获取当前列表

public ArrayList<Countries> GetCurrentListData() {
        return countryArrayList;
    }

CountryAdapter dcAdapter = new CountryAdapter("whatever your perameter");
    listview.setAdapter(dcAdapter);
    lstDoctorsList.setOnItemClickListener(new AdapterView.OnItemClickListener() {
                        @Override
                        public void onItemClick(AdapterView<?> parent, View view,
                                                int position, long id) {
                            try {
                                Countries countries = dcAdapter
                                     .GetCurrentListData().get(position);
                                // get data from countries model class

                            } catch (Exception e) {

                            }
                        }
                    });

【讨论】:

  • 它不会编译,因为匿名类......在onItemClick中不需要适配器引用......传递给这个方法的参数就是你所需要的......
  • 非常感谢!这工作100%!我的控制器中有一个方法,虽然它得到了国家列表,但由于某种原因,这不起作用,因为那是我要返回的
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-03-20
  • 1970-01-01
相关资源
最近更新 更多