2014-12-11 3 views
0

Мой вопрос в том, когда я фильтрую 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(); 
    } 
} 

ответ

1

идеология фильтрации адаптеров работает путем замены исходного списка данных Int он адаптер с отфильтрованного списка. Метод performFiltering расскажет вам, какие элементы в списке данных соответствуют вашему фильтру. Но не этот список делает основной список данных для вашего адаптера вместо исходного списка данных. Таким образом, вы shoudl сохраняете 2 списка в вашем адаптере.

  • Оригинальный нефильтрованный список. для справки
  • Второй список, который передает данные адаптеру. getView и getItems и т. Д. Методы должны использовать этот список.

Когда вы делаете 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(); 
      } 
     } 
    } 
+0

Thnks для ответа ого в качестве suggetion я должен использовать два baseadapter один для до того списка фильтров и секунды после того, как значения фильтра, заполненные методом performFiltering? –

+0

NO. не 2 базовых адаптера ..... 2 списка данных в одном адаптере. В вашем списке всегда должен быть установлен один адаптер. – Nazgul

+0

У меня есть, как будто это правда? потому что я не получаю никакого результата "\t защищенных недействительный publishResults (CharSequence ограничения, \t \t \t \t FilterResults результатов) { \t \t \t фиктивных = нового ArrayList (); \t \t \t doctorList = (ArrayList ) results.values; \t \t \t dummy = doctorList; \t \t \t для (INT I = 0; г

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); 
    } 
}); 
Смежные вопросы