简体   繁体   English

过滤器列表视图后位置错误

[英]Getting wrong position after filter listview

My question is when i filter listview with baseadapter than i got perfect result but after click on this item,i can't get related values of that item but i get wrong position item so notifydatasetchenged not work. 我的问题是,当我用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();
    }
}

}' }'

the ideology of filtering in adapters works by replacing the original data list int he adapter with the filtered list. 适配器中过滤的思想是通过将适配器中的原始数据列表替换为过滤后的列表来实现的。 The performFiltering method will tell you what elements in the data list match your filter. performFiltering方法将告诉您数据列表中的哪些元素与您的过滤器匹配。 But not this list makes the primary data list for your adapter instead of the original data list. 但是,此列表并非使适配器成为主要数据列表,而不是原始数据列表。 So you shoudl keep 2 lists in your adapter. 因此,您应该在适配器中保留2个列表。

  • The original unfiltered list. 原始未过滤列表。 for reference 以供参考
  • The second list which feeds data to the adapter. 第二个将数据馈送到适配器的列表。 getView and getItems etc. methods should use this list. getViewgetItems等方法应使用此列表。

When you do performFiltering use the original unfiltered list to extract matching data elements and save in the second list. 当您执行performFiltering时,请使用原始的未过滤列表提取匹配的数据元素并保存在第二个列表中。 That way you will never go wrong. 这样,您将永远不会出错。

Sample Example adapter for reference 样本示例适配器供参考

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();
            }
        }
    }

This worked for me 这对我有用

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);
    }
});

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM