Android ArrayAdapter 过滤问题

发布于 2024-09-28 12:03:54 字数 3413 浏览 8 评论 0原文

因为我想使用自定义列表适配器,以便我可以设置列表样式,但过滤器功能不起作用。我可以进行基本过滤,但是一旦过滤结果列表少于我开始过滤时显示的列表项数量,应用程序就会崩溃。

这段代码中还有第二个问题,我不确定它是否相关,但是当 clear(); 在publishResults 中运行,然后应用程序也会崩溃。

这是我正在使用的代码。

package com.android.example;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;

import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.Filter;
import android.widget.TextView;

public class CustomListAdapter extends ArrayAdapter<String> {
    private Context mContext; 
private String[] items;
private String[] filtered;

public CustomListAdapter(Context context, int textViewResourceId, String[] items) {
        super(context, textViewResourceId, items);
        this.filtered = items;
        this.items = filtered;

        setNotifyOnChange(true);
        mContext = context;
}

@Override
public View getView(int position, View convertView, ViewGroup parent) {
     View v = convertView;
     if (v == null) {
         LayoutInflater vi = (LayoutInflater)mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
         v = vi.inflate(R.layout.list_item, null);
     }
     String o = filtered[position];
     if (o != null) {
             TextView tt = (TextView) v.findViewById(R.id.tvViewRow);
             if (tt != null) {
                   tt.setText("Name: "+o);
             }
     }
     return v;
}

public void notifyDataSetInvalidated()
{
    super.notifyDataSetInvalidated();
}


private Filter filter;


public Filter getFilter()
{
    if(filter == null)
        filter = new NameFilter();
    return filter;
}
private class NameFilter extends Filter
{
    @Override
    protected FilterResults performFiltering(CharSequence constraint) {
        // NOTE: this function is *always* called from a background thread, and
        // not the UI thread.
        constraint = constraint.toString().toLowerCase();
        FilterResults result = new FilterResults();
        if(constraint != null && constraint.toString().length() > 0)
        {
            ArrayList<String> filt = new ArrayList<String>();
            List<String> lItems = new ArrayList<String>();
            synchronized (items)
            {     
                lItems = Arrays.asList(items);  
                //Collections.copy(lItems, Arrays.asList(items));
            }
            for(int i = 0, l = lItems.size(); i < l; i++)
            {
                String m = lItems.get(i);
                if(m.toLowerCase().startsWith(constraint.toString()))
                    filt.add(m);
            }
            result.count = filt.size();
            result.values = filt.toArray(new String[0]);
        }
        else
        {
            synchronized(items)
            {
                result.values = items;
                result.count = Arrays.asList(items).size();
            }
        }
        return result;
    }

    @Override
    protected void publishResults(CharSequence constraint, FilterResults results) {
        // NOTE: this function is *always* called from the UI thread.

            filtered = (String[])results.values;
            notifyDataSetChanged();
            clear();
            notifyDataSetInvalidated();
    }
}

}

As i wanted to use a Custom List Adapter so that I could style the list but the Filter functionality is not working. I got the basic filtering to work but the application crashes as soon as the list of filtered results is less than the number of listItems shown when I start filtering.

There is also a second problem I am having in this code that I am not sure if it is related but when the
clear(); gets run in the publishResults, then the application also crashes.

Here is the code I am using.

package com.android.example;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;

import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.Filter;
import android.widget.TextView;

public class CustomListAdapter extends ArrayAdapter<String> {
    private Context mContext; 
private String[] items;
private String[] filtered;

public CustomListAdapter(Context context, int textViewResourceId, String[] items) {
        super(context, textViewResourceId, items);
        this.filtered = items;
        this.items = filtered;

        setNotifyOnChange(true);
        mContext = context;
}

@Override
public View getView(int position, View convertView, ViewGroup parent) {
     View v = convertView;
     if (v == null) {
         LayoutInflater vi = (LayoutInflater)mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
         v = vi.inflate(R.layout.list_item, null);
     }
     String o = filtered[position];
     if (o != null) {
             TextView tt = (TextView) v.findViewById(R.id.tvViewRow);
             if (tt != null) {
                   tt.setText("Name: "+o);
             }
     }
     return v;
}

public void notifyDataSetInvalidated()
{
    super.notifyDataSetInvalidated();
}


private Filter filter;


public Filter getFilter()
{
    if(filter == null)
        filter = new NameFilter();
    return filter;
}
private class NameFilter extends Filter
{
    @Override
    protected FilterResults performFiltering(CharSequence constraint) {
        // NOTE: this function is *always* called from a background thread, and
        // not the UI thread.
        constraint = constraint.toString().toLowerCase();
        FilterResults result = new FilterResults();
        if(constraint != null && constraint.toString().length() > 0)
        {
            ArrayList<String> filt = new ArrayList<String>();
            List<String> lItems = new ArrayList<String>();
            synchronized (items)
            {     
                lItems = Arrays.asList(items);  
                //Collections.copy(lItems, Arrays.asList(items));
            }
            for(int i = 0, l = lItems.size(); i < l; i++)
            {
                String m = lItems.get(i);
                if(m.toLowerCase().startsWith(constraint.toString()))
                    filt.add(m);
            }
            result.count = filt.size();
            result.values = filt.toArray(new String[0]);
        }
        else
        {
            synchronized(items)
            {
                result.values = items;
                result.count = Arrays.asList(items).size();
            }
        }
        return result;
    }

    @Override
    protected void publishResults(CharSequence constraint, FilterResults results) {
        // NOTE: this function is *always* called from the UI thread.

            filtered = (String[])results.values;
            notifyDataSetChanged();
            clear();
            notifyDataSetInvalidated();
    }
}

}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

得不到的就毁灭 2024-10-05 12:03:54

我只是有同样的问题。只需将 getCount() 方法放入您的适配器类中即可。它应该返回过滤后的计数。像这样的事情:

public int getCount() {
    return mItems.size();  
}

我过滤 mItems。

I just have same problem. Just put getCount() method in your adapter class. It should return filtered count. Something like this:

public int getCount() {
    return mItems.size();  
}

I filter mItems.

笑脸一如从前 2024-10-05 12:03:54

尝试按以下方式更改您的publishResults方法:

 @Override
        public void publishResults(CharSequence constraint, FilterResults results) {

            List<T> filtered = (ArrayList<T>) results.values;
            adapter.notifyDataSetChanged();
            adapter.clear();
            if (filtered != null) {

            for (int i = 0; i < filtered.size(); i++)
                adapter.add(filtered.get(i));
            }
            adapter.notifyDataSetInvalidated();
        }

        }

Try to change your publishResults method in the following manner:

 @Override
        public void publishResults(CharSequence constraint, FilterResults results) {

            List<T> filtered = (ArrayList<T>) results.values;
            adapter.notifyDataSetChanged();
            adapter.clear();
            if (filtered != null) {

            for (int i = 0; i < filtered.size(); i++)
                adapter.add(filtered.get(i));
            }
            adapter.notifyDataSetInvalidated();
        }

        }
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文