简体   繁体   中英

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.

'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. 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.

  • The original unfiltered list. for reference
  • The second list which feeds data to the adapter. getView and getItems etc. methods should use this list.

When you do performFiltering use the original unfiltered list to extract matching data elements and save in the second list. 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);
    }
});

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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