过滤列表视图后出错位置

时间:2014-12-11 07:03:02

标签: java android android-activity

我的问题是当我用baseadapter过滤listview而不是我得到完美的结果但是点击这个项目后,我无法获得该项目的相关值,但我得到了错误的位置项目,因此notifydatasetchenged无效。

'public ConsultationAdpater(Context context, ArrayList<Doctor> doctors) {
    this.context = context;
    this.doctorList = doctors;
    this.mStringFilterList = doctors;
    getFilter();
    imageLoader = ImageLoader.getInstance();
    this.inflater = (LayoutInflater) context
            .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
    // set options for image display
    options = new DisplayImageOptions.Builder()
            .showImageOnLoading(R.drawable.activity_indicator)
            .showImageForEmptyUri(R.drawable.image_not_available)
            .showImageOnFail(R.drawable.image_not_available)
            .resetViewBeforeLoading(true).cacheInMemory(true)
            .cacheOnDisk(true).considerExifParams(true)
            .bitmapConfig(Bitmap.Config.RGB_565).build();

}

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

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

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

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

    if (convertView == null) {

        convertView = inflater.inflate(R.layout.row_consult, parent, false);

        holder = new ViewHolder();
        holder.image = (ImageView) convertView
                .findViewById(R.id.img_row_const);
        holder.txtName = (TextView) convertView
                .findViewById(R.id.tDtNm_row_const);
        holder.txtSpeciality = (TextView) convertView
                .findViewById(R.id.tDtPt_row_const);
        holder.txtPrice = (TextView) convertView
                .findViewById(R.id.tDtPr_row_const);

        convertView.setTag(holder);
    } else {
        holder = (ViewHolder) convertView.getTag();
    }

    Doctor doctor = doctorList.get(position);
    holder.txtName.setText(doctor.base_user.first_name);
    holder.txtSpeciality.setText(doctor.specialization);
    holder.txtPrice.setText(doctor.cost_per_minute + "$/min");

    if (images[position] == null) {
        holder.image.setImageResource(R.drawable.image_not_available);
    } else {
        imageLoader.displayImage(
                "http://37.252.121.94/" + images[position], holder.image,
                options);

    }

    return convertView;
}

public void switchDoctorList(ArrayList<Doctor> doctors, String[] images) {
    this.doctorList = doctors;
    this.mStringFilterList = doctors;
    this.images = images;
    this.notifyDataSetChanged();
}

public void switchDoctorList(ArrayList<Doctor> doctors) {
    this.doctorList = doctors;
    this.mStringFilterList = doctors;
    this.notifyDataSetChanged();
}

private static class ViewHolder {
    ImageView image;
    TextView txtName;
    TextView txtSpeciality;
    TextView txtPrice;
}

@Override
public Filter getFilter() {
    if (valueFilter == null) {

        valueFilter = new ValueFilter();
    }

    return valueFilter;
}

private class ValueFilter extends Filter {

    // Invoked in a worker thread to filter the data according to the
    // constraint.
    @Override
    protected FilterResults performFiltering(CharSequence constraint) {
        FilterResults results = new FilterResults();

        if (constraint != null && constraint.length() > 0) {
            ArrayList<Doctor> filterList = new ArrayList<Doctor>();
            for (int i = 0; i < mStringFilterList.size(); i++) {
                if ((mStringFilterList.get(i).specialization.toUpperCase())
                        .contains(constraint.toString().toUpperCase())) {

                    filterList.add(mStringFilterList.get(i));
                }
            }
            results.count = filterList.size();
            results.values = filterList;
        } else {
            results.count = mStringFilterList.size();
            results.values = mStringFilterList;
        }
        return results;
    }

    // Invoked in the UI thread to publish the filtering results in the user
    // interface.
    @SuppressWarnings("unchecked")
    @Override
    protected void publishResults(CharSequence constraint,
            FilterResults results) {
        doctorList = (ArrayList<Doctor>) results.values;
        notifyDataSetChanged();
    }
}

}&#39;

2 个答案:

答案 0 :(得分:1)

适配器中的过滤意识形态通过将适配器中的原始数据列表替换为已过滤的列表来实现。 performFiltering方法会告诉您数据列表中的哪些元素与您的过滤器匹配。但是,此列表不会生成适配器的主数据列表,而是原始数据列表。因此,您应该在适配器中保留2个列表。

  • 原始未经过滤的列表。供参考
  • 将数据提供给适配器的第二个列表。 getViewgetItems等方法应使用此列表。

执行performFiltering时,使用原始未过滤列表提取匹配的数据元素并保存在第二个列表中。这样你永远不会出错。

示例示例适配器供参考

public class CompanyQuotesResultAdapter extends BaseAdapter{

    //original data populated from DB or web service.
    private ArrayList<MyDataVO> originalData;

    //the data list which the adapter uses for its work
    private ArrayList<MyDataVO> data;
    private LayoutInflater inflater = null;
    private Fragment parentFragment;
    private Filter dataFilter;
    private int quoteGreenColor = -1;

    public CompanyQuotesResultAdapter(Fragment parentFragment){
        //set values here
    }

    public ArrayList<MyDataVO> getData() {
        return new ArrayList<MyDataVO>(this.data);
    }

    public ArrayList<MyDataVO> getOriginalData() {
        return new ArrayList<MyDataVO>(this.originalData);
    }

    public void addDataVOsWithoutNotification(List<MyDataVO> dataVOs){
        this.data.addAll(dataVOs);
        this.originalData.addAll(dataVOs);
    }

    public void setData(List<MyDataVO> data) {
        this.data = new ArrayList<MyDataVO>(data);
        this.originalData = new ArrayList<MyDataVO>(data);
        this.notifyDataSetChanged();
    }

    public boolean isEmpty() {
        return this.data.isEmpty();
    }

    public void clearAll(){
        this.originalData.clear();
        this.data.clear();
        this.notifyDataSetChanged();
    }

    public void clearAllWithoutNotification(){
        this.data.clear();
        this.originalData.clear();
    }

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

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

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

    public Filter getFilter(){
        return dataFilter;
    }

    //Filtering class
    private class ArrayFilter extends Filter {
        @Override
        protected FilterResults performFiltering(CharSequence prefix) {
            FilterResults results = new FilterResults();

            if (prefix == null || prefix.length() == 0) {
                ArrayList<MyDataVO> list = new ArrayList<MyDataVO>(originalData);
                results.values = list;
                results.count = list.size();
            } else {
                String prefixString = prefix.toString().toLowerCase(Locale.ENGLISH);

                ArrayList<MyDataVO> values = new ArrayList<MyDataVO>(originalData);

                final int count = values.size();
                final ArrayList<MyDataVO> newValues = new ArrayList<MyDataVO>();

                for (int i = 0; i < count; i++) {
                    final MyDataVO resultRowVO = values.get(i);
                    final String valueText = resultRowVO.getCompanyName().toLowerCase(Locale.ENGLISH);

                    // First match against the whole, non-splitted value
                    if (valueText.contains(prefixString)) {
                        newValues.add(resultRowVO);
                    }else{
                        final String codeValueText = resultRowVO.getCompanyCode().toLowerCase(Locale.ENGLISH);
                        if (codeValueText.contains(prefixString)) {
                            newValues.add(resultRowVO);
                        }
                    }
                }
                results.values = newValues;
                results.count = newValues.size();
            }
            return results;
        }

        protected void publishResults(CharSequence constraint, FilterResults results) {
            data = (ArrayList<MyDataVO>) results.values;
            if (results.count > 0) {
                notifyDataSetChanged();
            } else {
                notifyDataSetInvalidated();
            }
        }
    }

答案 1 :(得分:1)

这对我有用

mListView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
    @Override
    public void onItemClick(AdapterView<?> parent, final View view, int position, long id) {
        //abrirActividadDetallada(position, id);
        Object MyObject=(Object) parent.getAdapter().getItem(position);
        CustomMethod(MyObject);
    }
});