【问题标题】:Error while using filtering on android listview?在android listview上使用过滤时出错?
【发布时间】:2013-06-29 10:45:21
【问题描述】:

我正在尝试在 android 应用程序中向我的列表视图添加过滤。它无法正常工作,因为在我的搜索框中写了 3-4 个字母后出现以下异常。

07-02 12:14:48.348: E/AndroidRuntime(22028): FATAL EXCEPTION: main
07-02 12:14:48.348: E/AndroidRuntime(22028): java.lang.IndexOutOfBoundsException: Invalid index 1, size is 1
07-02 12:14:48.348: E/AndroidRuntime(22028):    at java.util.ArrayList.throwIndexOutOfBoundsException(ArrayList.java:251)
07-02 12:14:48.348: E/AndroidRuntime(22028):    at java.util.ArrayList.get(ArrayList.java:304)
07-02 12:14:48.348: E/AndroidRuntime(22028):    at android.widget.ArrayAdapter.getItem(ArrayAdapter.java:337)
07-02 12:14:48.348: E/AndroidRuntime(22028):    at com.sphinx.indianrailways.adapters.CityAdapter.getView(CityAdapter.java:57)
07-02 12:14:48.348: E/AndroidRuntime(22028):    at android.widget.AbsListView.obtainView(AbsListView.java:2143)
07-02 12:14:48.348: E/AndroidRuntime(22028):    at android.widget.ListView.makeAndAddView(ListView.java:1831)
07-02 12:14:48.348: E/AndroidRuntime(22028):    at android.widget.ListView.fillDown(ListView.java:674)
07-02 12:14:48.348: E/AndroidRuntime(22028):    at android.widget.ListView.fillSpecific(ListView.java:1332)
07-02 12:14:48.348: E/AndroidRuntime(22028):    at android.widget.ListView.layoutChildren(ListView.java:1630)
07-02 12:14:48.348: E/AndroidRuntime(22028):    at android.widget.AbsListView.onLayout(AbsListView.java:1994)
07-02 12:14:48.348: E/AndroidRuntime(22028):    at android.view.View.layout(View.java:14008)
07-02 12:14:48.348: E/AndroidRuntime(22028):    at android.view.ViewGroup.layout(ViewGroup.java:4373)
07-02 12:14:48.348: E/AndroidRuntime(22028):    at android.widget.LinearLayout.setChildFrame(LinearLayout.java:1663)
07-02 12:14:48.348: E/AndroidRuntime(22028):    at android.widget.LinearLayout.layoutVertical(LinearLayout.java:1521)
07-02 12:14:48.348: E/AndroidRuntime(22028):    at android.widget.LinearLayout.onLayout(LinearLayout.java:1434)
07-02 12:14:48.348: E/AndroidRuntime(22028):    at android.view.View.layout(View.java:14008)
07-02 12:14:48.348: E/AndroidRuntime(22028):    at android.view.ViewGroup.layout(ViewGroup.java:4373)
07-02 12:14:48.348: E/AndroidRuntime(22028):    at android.widget.FrameLayout.onLayout(FrameLayout.java:448)
07-02 12:14:48.348: E/AndroidRuntime(22028):    at android.view.View.layout(View.java:14008)
07-02 12:14:48.348: E/AndroidRuntime(22028):    at android.view.ViewGroup.layout(ViewGroup.java:4373)

我的过滤代码如下所示:

filterTextWatcher = new TextWatcher() {

            @Override
            public void onTextChanged(CharSequence cs, int start, int before,
                    int count) {
                // When user changed the Text by typing in search box
                adapter.getFilter().filter(cs);
            }

            @Override
            public void beforeTextChanged(CharSequence arg0, int arg1,
                    int arg2, int arg3) {
                // TODO Auto-generated method stub

            }

            @Override
            public void afterTextChanged(Editable arg0) {
                // TODO Auto-generated method stub
            }
        };

        citySearchBox.addTextChangedListener(filterTextWatcher);

我的 StationAdapter.java 代码是:

    public class CityAdapter extends ArrayAdapter<City> {
    ArrayList<City> cityLists = new ArrayList<City>();
    private Context context;
    public String noInternet = "No network connectivity.Try again later.";
    City city= null;

    public CityAdapter(Context context, int textViewResourceId,
            ArrayList<City> cityLists) {
        super(context, textViewResourceId, cityLists);
        this.context = context;
        this.cityLists = cityLists;
    }

    static class ViewHolder {
        protected TextView cityCode;
        protected TextView cityName;
    }

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

    @Override
    public View getView(final int position, View convertView, ViewGroup parent) {
        // TODO Auto-generated method stub

        ViewHolder holder = null;
        if (convertView == null) {
            LayoutInflater inflator = ((Activity) context).getLayoutInflater();
            convertView = inflator.inflate(R.layout.single_city_item, null);
            holder = new ViewHolder();

            holder.cityCode = (TextView) convertView
                    .findViewById(R.id.cityCode);
            holder.cityName = (TextView) convertView
                    .findViewById(R.id.cityName);
            convertView.setTag(holder);
        } else {
            holder = (ViewHolder) convertView.getTag();
        }
        city= getItem(position);

        holder.cityCode.setText(city.getCityCode());
        holder.cityName.setText(city.getCityName());
        return convertView;
    }
}

我知道当时 arraylist 可能有 1 个元素,它试图通过 list[1] 访问它,这会引发 nullpointerexception。但是我需要在我的代码中更改什么来解决这个问题。

【问题讨论】:

  • 请显示CityAdapter实现
  • @Mohamed_AbdAllah 我添加了 CityAdapter 代码。请帮助
  • 我没有看到你在适配器内的任何地方使用城市变量,为什么city= getItem(position);这一行
  • @Mohamed_AbdAllah 我在 adpater 的 getView() 方法中使用它。请再次查看代码。
  • 我可以看到。我的问题是你为什么要使用它(你没有在 city= getItem(position); 行之后将它分配给适配器中的任何其他东西)?!这是您的问题所在,因此如果您不使用它,请将其删除

标签: android android-listview filtering


【解决方案1】:

经过我们的讨论,我认为问题出在这条线上:

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

这使得适配器认为它的大小比正常的大(因为它的大小是固定的并且在你过滤后没有改变)并且在调用getView() (city= getItem(position);) 时无法获取我们的边界项.

您应该实现Filterable 接口(@98​​7654328@),如问题12 和这个example。这将在每次调用getFilter() 时更新cityLists Array,其大小会正常返回,也会更新Adapter (notifyDataSetChanged())

编辑

另一种方法是删除您的getCount()(让超级方法生效)。这将在每次应用过滤器时更新大小,而不是返回固定的cityLists.size(),并让适配器认为它的大小大于它拥有的数据。基本上,您可以像以前一样实现getCount(),另外添加getFilter() 以在每次过滤时更改cityLists 的大小,或者让系统同时处理两者(不要实现getFilter()getCount()

【讨论】:

  • 感谢@Mohamed 的解释
猜你喜欢
  • 1970-01-01
  • 2020-12-31
  • 2013-03-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-12-12
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多