繁体   English   中英

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

[英]Getting wrong position after filter listview

我的问题是,当我用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();
    }
}

}'

适配器中过滤的思想是通过将适配器中的原始数据列表替换为过滤后的列表来实现的。 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();
            }
        }
    }

这对我有用

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