2013-03-04 16 views
8

Sono novizio in Android.filtering adapter personalizzato IndexOutOfBoundsException

Il mio adattatore personalizzato causa un'eccezione durante il filtraggio.

ecco il mio codice. classe DeptAdapter privato estende ArrayAdapter implementa filtrabili {

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

mi aiuto a nessuno .... non riesco a capire il motivo per cui il metodo GetView() è stato richiamato più di items.size()

+0

Si prega di aggiungere codice completo di DeptAdapter classe e logcat uscita –

+1

voglio anche il codice dei due metodi getCount() e getItem (int position) –

risposta

16

Tenete a mente che getView() sarà interrogare la dimensione degli elementi che l'superclass ha, che in questo momento, è quello che si originariamente passò quando si chiama il costruttore della superclasse,

super(context, textViewResourceId, items); 

Pertanto, la superclasse non sa che hai cambiato le dimensioni quando hai filtrato. Ciò significa che getCount() restituirà la dimensione originale dell'array, che è comprensibilmente più grande dell'array filtrato.

Ciò significa che dovreste eseguire l'override del metodo getCount() così sei sicuro che si sta tornando la dimensione valida reale:

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

si dovrebbe anche ignorare gli altri metodi relativi alle operazioni List (come ottenere) se li stai usando. Ad esempio:

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

Grazie mille !! La tua risposta è stata in grado di risolvere completamente il mio problema. – user1788012

+1

Salvato tutto il giorno – Nabin

+1

Ho avuto lo stesso problema e la soluzione ha funzionato anche per me. Grazie! – user2151486

0

Ti manca getCount() metodo, un'occhiata a questo demo

Spero che sarà utile!

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' è un segnaposto mentre il filtro è attivo. Non è necessario conservare gli articoli dall'inizio. –

+0

if (mOriginalValues ​​== null) {mOriginalValues ​​= new ArrayList (articoli); // salva i dati originali in mOriginalValues} che vedi qui per primo uso e poi inizializza bro @ A - C – QuokMoon

+0

Viene inizializzato lì se è nullo, ed è lì che si salva una copia. Assegnare nel costruttore è un buon fail-safe, ma il controllo 'null' è già presente quando si filtra per un motivo. 'this.mOriginalValues ​​= items;' non è necessario nel costruttore. –

1

È necessario aggiungere questo metodi per migliorare le prestazioni:

 @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; 
     } 
Problemi correlati