ArrayAdapter Filteration仅适用于第一次。下一个输入失败

时间:2016-09-09 08:03:00

标签: listview android-arrayadapter android-filter

我在ArrayAdapter对象的自定义列表中应用了一个过滤器。我申请了过滤,它只是第一次工作。当我尝试删除过滤后的文本并输入另一个时,它无法在ListView中为我提供更新数据。这是我的代码,

适配器类

public class ServiceListAdapter extends ArrayAdapter<ServiceItem> implements Filterable {

private Context mContext;
private List<ServiceItem> serviceItemList;
private List<ServiceItem> nameList;
private LayoutInflater inflater;
private int layoutId;
private ServiceFilter filter;


public ServiceListAdapter(Context context, int resource, List<ServiceItem> serviceItemList) {
    super(context, resource, serviceItemList);

    this.mContext = context;
    this.serviceItemList = serviceItemList;
    this.layoutId = resource;
    this.inflater = (LayoutInflater) getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}

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

    View v = convertView;
    ServiceHolder sHolder = null;

    if (v == null) {

        v = inflater.inflate(layoutId, null);

        sHolder = new ServiceHolder();
        sHolder.serviceName = (TextView) v.findViewById(R.id.serviceName);
        sHolder.serviceDetail = (TextView) v.findViewById(R.id.serviceDetail);
        sHolder.serviceImg = (ImageView) v.findViewById(R.id.serviceImg);
        sHolder.btnGo = (Button) v.findViewById(R.id.btnGo);

        v.setTag(sHolder);
    } else {

        sHolder = (ServiceHolder) convertView.getTag();
    }

    ServiceItem serviceItem = getItem(position);
    sHolder.serviceName.setText(serviceItem.getServiceName());
    sHolder.serviceDetail.setText(serviceItem.getServiceDetail());
    sHolder.serviceImg.setImageResource(serviceItem.getServiceImg());

    sHolder.btnGo.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {


        }
    });


    return v;
}

static class ServiceHolder {

    TextView serviceName;
    TextView serviceDetail;
    ImageView serviceImg;
    Button btnGo;

}

@Override
public ServiceItem getItem(int position) {
    return serviceItemList.get(position);
}

@Override
public Filter getFilter() {

    if (filter == null) {
        filter = new ServiceFilter();
    }
    return filter;

}

private class ServiceFilter extends Filter {


    private static final String TAG = "Filter";

    @Override
    protected FilterResults performFiltering(CharSequence constraint) {


        FilterResults filterResults = new FilterResults();


        Log.d(TAG, "Length: " + constraint.toString().length());

        if (constraint != "" && constraint.toString().length() > 0) {

            ArrayList<ServiceItem> filterItems = new ArrayList<>();
            ArrayList<ServiceItem> sItems = new ArrayList<>();

            synchronized (this)
            {
                sItems.addAll(serviceItemList);
            }

            constraint = constraint.toString().toLowerCase();

            Log.d(TAG, "To Compare:: " + constraint);

            for (int l = 0; l< sItems.size(); l++) {

                Log.d(TAG, "sItems Size:" + sItems.size());

                ServiceItem sItem = sItems.get(l);
                String name = sItem.toString();
                Log.d(TAG, "Name: " + name);

                if (name.startsWith(constraint.toString().toLowerCase())){
                    Log.d(TAG, "Added: " + name);
                    filterItems.add(sItem);
                }

            }
             Log.d(TAG, "Filter Item Size: " + filterItems.size());

            filterResults.count = filterItems.size();
            filterResults.values = filterItems;

        } else {

            synchronized (this) {

                Log.d(TAG, "performFiltering: ORIGINAL ");
                Log.d(TAG, "Filter Item Size: " + serviceItemList.size());

                filterResults.values = serviceItemList;
                filterResults.count = serviceItemList.size();

            }
        }

        Log.d(TAG, "Count:" + filterResults.count);

        return filterResults;
    }


    @SuppressWarnings("unchecked")
    @Override
    protected void publishResults(CharSequence constraint, FilterResults results) {
        /*nameList is List<ServiceItem> declared in root class*/

        nameList = (ArrayList<ServiceItem>) results.values;

        notifyDataSetChanged();
        clear();
        for(int i = 0, l = nameList.size(); i < l; i++)
            add(nameList.get(i));
        notifyDataSetInvalidated();
    }
}

}

EditText TextWatcher代码

edtFilterText.addTextChangedListener(new TextWatcher() {
        @Override
        public void beforeTextChanged(CharSequence s, int start, int count, int after) {
        }

        @Override
        public void onTextChanged(CharSequence s, int start, int before, int count) {
        }

        @Override
        public void afterTextChanged(Editable s) {

            Log.d("Filter", "beforeTextChanged: " +s);
            serviceListAdapter.getFilter().filter(s.toString().toLowerCase());
        }
    });

所以,我第一次得到了过滤的结果。然后,当我试图更改editText内容时,它显示我没有过滤项目的结果,并且还将主服务项目列表大小显示为零而没有项目。

帮助我解决这个问题,我已经尝试了很多答案,但我的结果是这样的。

1 个答案:

答案 0 :(得分:0)

对于你的信息,我用它来解决它

// Filter Class public void filter(String charText) { charText = charText.toLowerCase(Locale.getDefault()); serviceItemList.clear(); if (charText.length() == 0) { serviceItemList.addAll(nameList); } else { for (ServiceItem si : nameList) { if (si.getServiceName().toLowerCase(Locale.getDefault()).contains(charText)) { serviceItemList.add(si); } } } notifyDataSetChanged(); }

并且调用方法与前一个方法相同,只是稍作修改,

serviceListAdapter.filter(s.toString().toLowerCase());

有关更多信息,它不是我们必须从Filter类实现的方法。它的手动方法就像魅力一样。