2013-03-04 17 views
8

Ich bin Anfänger bei Android.Filtern von benutzerdefinierten Adapter IndexOutOfBoundsException

Mein benutzerdefinierter Adapter verursacht beim Filtern eine Ausnahme.

Hier ist mein Code. private Klasse DeptAdapter erweitert ArrayAdapter Filterbare implementiert {

private ArrayList<Dept> items; 
    private ArrayList<Dept> mOriginalValues; 

    public DeptAdapter(Context context, int textViewResourceId, ArrayList<Dept> items) { 
      super(context, textViewResourceId, items); 
      this.items = items; 
    } 
    @Override 
    public View getView(int position, View convertView, ViewGroup parent) { 
     View v = convertView; 

     if (v == null) { 
      LayoutInflater vi = (LayoutInflater)getSystemService(Context.LAYOUT_INFLATER_SERVICE); 
      v = vi.inflate(R.layout.item_listview_2line, null); 
     } 
     Dept d = items.get(position); 
     if (d != null) { 
       TextView tt = (TextView) v.findViewById(R.id.toptext); 
       TextView bt = (TextView) v.findViewById(R.id.bottomtext); 
       if (tt != null){ 
        tt.setText(d.dept_nm);        
       } 
       if(bt != null){ 
        bt.setText(d.dept_cd); 
       } 
     } 
     return v; 
    } 

    @Override 
    public Filter getFilter() { 
     Filter filter = new Filter() { 

      @SuppressWarnings("unchecked") 
      @Override 
      protected void publishResults(CharSequence constraint,FilterResults results) { 

       items = (ArrayList<Dept>) results.values; // has the filtered values 
       if (results.count > 0) { 
        notifyDataSetChanged(); 
       } else { 
        notifyDataSetInvalidated(); 
       } 
      } 

      } 
      @Override 
      protected FilterResults performFiltering(CharSequence constraint) { 
       FilterResults results = new FilterResults();  // Holds the results of a filtering operation in values 
       ArrayList<Dept> FilteredArrList = new ArrayList<Dept>(); 

       if (mOriginalValues == null) { 
        mOriginalValues = new ArrayList<Dept>(items); // saves the original data in mOriginalValues 
       } 

       if (constraint == null || constraint.length() == 0) { 

        // set the Original result to return 
        results.count = mOriginalValues.size(); 
        results.values = mOriginalValues; 
       } else { 
        constraint = constraint.toString().toLowerCase(); 
        for (int i = 0; i < mOriginalValues.size(); i++) { 
         Dept d = mOriginalValues.get(i); 
         if (d.dept_cd.toLowerCase().startsWith(constraint.toString()) || d.dept_nm.toLowerCase().startsWith(constraint.toString())) { 
          FilteredArrList.add(d); 
         } 
        } 
        // set the Filtered result to return 
        results.count = FilteredArrList.size(); 
        results.values = FilteredArrList; 
       } 
       return results; 
      } 
     }; 
     return filter; 
    } 
} 

class Dept 
{ 
    String dept_cd; 
    String dept_nm; 
    public Dept(String dept_cd, String dept_nm) 
    { 
     this.dept_cd = dept_cd; 
     this.dept_nm = dept_nm; 
    } 
    public String toString() 
    { 
     return this.dept_nm+ "(" + this.dept_cd +")" ; 
    } 
} 

Hilfe jemand mir .... Ich kann nicht verstehen, warum getView() -Methode mehr aufgerufen wurde dann items.size()

+0

Bitte füge vollständigen Code von DeptAdapter Klasse und logcat Ausgabe –

+1

Ich mag auch Code der beiden Methoden getCount() und getItem (int Position) –

Antwort

16

Beachten dass getView() die Größe der Elemente abfragt, die die superclass hat, die gerade jetzt, ist das, was Sie ursprünglich es übergeben, wenn die Oberklassenkonstruktors Aufruf

super(context, textViewResourceId, items); 

Daher weiß die Oberklasse nicht, dass Sie die Größe geändert haben, wenn Sie gefiltert haben. Das bedeutet, dass getCount() die ursprüngliche Größe des Arrays zurückgibt, die verständlicherweise größer als Ihr gefiltertes Array ist. Diese

bedeutet Sie sollten die getCount() Methode überschreiben, so dass Sie sicher sind, dass Sie die aktuell gültigen Größe sind Rückkehr:

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

Sie sollten auch die anderen Methoden, um die Liste Operationen zusammenhängen außer Kraft setzen (wie immer) wenn Sie sie benutzen. ZB:

@Override 
public Dept getItem (int pos){ 
    return items.get(pos); 
} 
+1

Vielen Dank !! Ihre Antwort hat mein Problem vollständig gelöst. – user1788012

+1

Ich habe den ganzen Tag gespeichert – Nabin

+1

Ich hatte das gleiche Problem und Ihre Lösung hat auch für mich funktioniert. Vielen Dank! – user2151486

0

Sie vermissen getCount() Methode, Blick auf diese demo

Ich hoffe, es wird hilfreich sein!

0
private ArrayList<Dept> items; 
    private ArrayList<Dept> mOriginalValues; 

    public DeptAdapter(Context context, int textViewResourceId, ArrayList<Dept> items) { 
      super(context, textViewResourceId, items); 
      this.items = items; 
      this.mOriginalValues=items; //add this line in your code 
    } 
+0

'mOriginalValues' ist ein Platzhalter während der Filterung vorhanden ist. Es muss nicht von Anfang an an den Gegenständen festhalten. –

+0

if (mOriginalValues ​​== null) {mOriginalValues ​​= neue ArrayList (Elemente); // speichert die ursprünglichen Daten in mOriginalValues} Sie sehen hier zuerst verwenden und dann initialisieren bro @ A - C – QuokMoon

+0

Es ist dort initialisiert, wenn es null ist, und das ist, wo Sie eine Kopie speichern. Die Zuweisung im Konstruktor ist eine gute Ausfallsicherung, aber die 'Null'-Prüfung ist bereits vorhanden, wenn Sie nach einem Grund filtern. 'this.mOriginalValues ​​= items;' wird im Konstruktor nicht benötigt. –

1

Sie benötigen diese Methoden für eine bessere Leistung hinzuzufügen:

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

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

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