Autore Topic: adapter -- metodo getView() che restituisce errore di IndexOutOfBound  (Letto 608 volte)

Offline pablo86

  • Nuovo arrivato
  • *
  • Post: 8
  • Respect: 0
    • Mostra profilo
  • Dispositivo Android:
    AVD: HVGA
  • Sistema operativo:
    Windows XP
Salve,

quello che vorrei fare è una lista che visualizza 5 elementi per volta.
Quando si clicca sul pulsante avanti vengono visualizzati i 5 elementi successivi, se non ce ne sono altri 5 vorrei visualizzare solo quelli che sono rimasti.

Ad esempio se ho 12 elementi:
inizialmente vengono visualizzati i primi 5.
Cliccando su avanti, viene aggiornata la listView e vengono visualizzati i successivi 5 elementi.
Siamo quindi a 10(come indice).Fin qui tutto ok.

Quando viene cliccato nuovamente il pulsante Avanti, la mia app "crasha",
come errore nel LogCat mi dice che all'interno del metodo getView() del mio custo adapter, l'istruzione item.get(position) dà una outOfBoundException: Index 1, size is 1.

Non capisco perchè non mi fa visualizzare gli ultimi 2 elementi.Quello che vorrei è che quando si clicca nuovamente su AVANTI mi visualizzi gli altri 2 che sono rimasti.
La cosa strana è che se metto 15 elementi nella lista và tutto bene.
Come se ogni volta sono obbligato a visualizzare 5 elementi, anche se in realtà ne sono rimasti di meno(ad esempio 2).

Vi posto un pò di codice:
Codice (Java): [Seleziona]
public class TerzaActivity extends ListActivity implements OnClickListener{

       
        private ArrayList<Poi> Pois = new ArrayList<Poi>();
        LocationManager locManager;
        int due_volte_indietro=0;
        Location myLastLoc;
        String locProvider;
        int count_indice_pois_avanti;
        int count_indice_pois_indietro;
        ListView lista;
        ArrayList<Poi> pois_disp = new ArrayList<Poi>();
        Button Mappa,Aggiungi,Avanti,Indietro;
        PoiAdapter p_adapter;
       
        @Override
        public void onCreate(Bundle savedInstanceState) {
                super.onCreate(savedInstanceState);
                Intent intent = getIntent();
                setContentView(R.layout.cerca);
                count_indice_pois_avanti=0;

                Avanti = (Button) findViewById(R.id.bottoneAvanti);

                Indietro = (Button) findViewById(R.id.bottoneIndietro);
                Indietro.setVisibility(View.INVISIBLE);
               
            Mappa = (Button) findViewById(R.id.bottoneMappa);
            Mappa.setOnClickListener(this);
           
            Aggiungi = (Button) findViewById(R.id.bottoneAggiungi);
            Aggiungi.setOnClickListener(this);
               
                 // attiviamo il servizio di localizzazione
             locManager = (LocationManager)getSystemService(LOCATION_SERVICE);
             locProvider = LocationManager.GPS_PROVIDER;
             myLastLoc = locManager.getLastKnownLocation(locProvider);
             Location loc = new Location(locProvider);
       
             for(String s : intent.getStringArrayListExtra("categorie")){
                       
                        Cursor constantsCursor=null;
                        // interroghiamo il db
                        constantsCursor=mainActivity.dbPoi.rawQuery("SELECT * FROM poi WHERE categoria='"+s+"' ",
                                                                        null);
                        //prova.setText("cursore count= "+constantsCursor.getCount());
                        constantsCursor.moveToFirst();
                       
                        while(!constantsCursor.isAfterLast()){//scorro i risultati
                               
                                loc.setLatitude(constantsCursor.getDouble(4));//lat del POI nel db
                        loc.setLongitude(constantsCursor.getDouble(5));//lon del POI nel db
                       
                        /* filtro i POI nei risultati e prendo solo quelli che hanno una distanza
                         * minore del raggio impostato dall'utente rispetto alla mia posizione attuale  */

                                if( loc.distanceTo(myLastLoc) <= intent.getDoubleExtra("raggio", 2000.00)){
                                       
                                        //prova2.setText("arriba-- raggio= "+intent.getDoubleExtra("raggio", 2000.00));
                                        /* creo il POI e lo aggiungo alla lista dei POI da restituire */
                                        Poi p = new Poi();
                                        p.nome = constantsCursor.getString(1);
                                        p.categoria = constantsCursor.getString(2);
                                        p.lat = constantsCursor.getDouble(4);
                                        p.lon = constantsCursor.getDouble(5);
                                        p.dist = loc.distanceTo(myLastLoc);
                                        Pois.add(p);                                           
                                }
                                constantsCursor.moveToNext();
                               
                        }
                        constantsCursor.close();
                }
             
                sort_dist(Pois);//sort_dist è un metodo implementato per ordinare in modo crescente i POI in base alla loro distanza dalla mia posizione attuale
               
                if(Pois.size()>5){//ci sono più di 5 poi nei risultati, quindi deve comparire il pulsante avanti
                        for(int i=0;i<5;i++){
                                pois_disp.add(Pois.get(i));
                               
                        }
                        count_indice_pois_avanti = 5;
                    Avanti.setOnClickListener(this);
                }
                else{//nai risultati ci sono meno di 5 poi, quindi il pulsante avanti non deve comparire
                        for(int i=0;i<Pois.size();i++){
                                pois_disp.add(Pois.get(i));
                               
                        }
                        Avanti.setVisibility(View.INVISIBLE);
                        count_indice_pois_avanti = Pois.size();
                }
               
                /* visualizzo i risultati */
            p_adapter = new PoiAdapter(this, R.layout.riga, pois_disp);
            setListAdapter(p_adapter);
            lista=getListView();
                       
        }
       
       
        void sort_dist(ArrayList<Poi>  pois)
        {
                Poi temp = new Poi(); /* Indice temporaneo per scambiare elementi */
                int prossimo;
                int attuale;
                for (prossimo=1;prossimo<pois.size();prossimo++)
                {
                        temp=pois.get(prossimo);
                        attuale=prossimo-1;
                        while ((attuale>=0) && (pois.get(attuale).dist>temp.dist))
                        {
                                pois.set(attuale+1, pois.get(attuale));
                                attuale=attuale-1;
                        }
                        pois.set(attuale+1, temp);
                }
        }
       
        /* custom adapter per la gestione del tipo di dato poi all'interno della lista */
        private class PoiAdapter extends ArrayAdapter<Poi> {

        private int id;
                private ArrayList<Poi> items;
                private Context context;

        public PoiAdapter(Context context, int ViewResourceId, ArrayList<Poi> items) {
                super(context, ViewResourceId, items);
                this.items = items;
                this.id = ViewResourceId;
                this.context = context;
        }

        @Override
        public View getView(int position, View convertView, ViewGroup parent) {
                System.out.println("getView " + position + " " + convertView);
                        View v = convertView;
                if (v == null) {
                    LayoutInflater vi = (LayoutInflater)getSystemService(Context.LAYOUT_INFLATER_SERVICE);
                    v = vi.inflate(R.layout.riga, null);
                }
               // if(position>=items.size())return null;
                Poi o = items.get(position);
               
                if (o != null) {
                                ImageView im = (ImageView) v.findViewById(R.id.imm_1);
                        TextView tt = (TextView) v.findViewById(R.id.poi_1);
                        TextView bt = (TextView) v.findViewById(R.id.dist_1);
                        if (im != null){
                                int im_id;
                                if(o.categoria.compareTo("museo")==0){//la categoria del poi è museo
                                         
                                        im_id = getResources().getIdentifier("museo", "drawable", getPackageName());
                                }
                                else if(o.categoria.compareTo("cinema")==0){
                                         im_id = getResources().getIdentifier("cinema", "drawable", getPackageName());
                                }
                                else if(o.categoria.compareTo("ristorante")==0){
                                         im_id = getResources().getIdentifier("ristorante", "drawable", getPackageName());
                                }
                                else if(o.categoria.compareTo("bar")==0){
                                         im_id = getResources().getIdentifier("bar", "drawable", getPackageName());
                                }
                                else if(o.categoria.compareTo("shopping")==0){
                                         im_id = getResources().getIdentifier("supermercato", "drawable", getPackageName());
                                }
                                else{
                                         im_id = getResources().getIdentifier("icon", "drawable", getPackageName());                   
                                }
                                im.setImageResource(im_id);
                        }
                        if (tt != null) {
                              tt.setText(o.nome);                            }
                        if(bt != null){
                              bt.setText(""+ arrotondaPerEccesso(o.dist, 2)+" m");
                        }
                }
                return v;
        }
       
        }
       
        /* metodo che gestisce il click su uno dei poi visualizzati */
        public void onListItemClick(ListView parent, View v, int position, long id) {
               
                Intent poi_inf = new Intent(this,DettPoi.class);
                poi_inf.putExtra("poi", pois_disp.get(position));
                startActivity(poi_inf);
        }

        /* metodo che gestisce gli eventi click sui pulsanti  */
        public void onClick(View v) {
                if(v == Avanti){//viene cliccato 'Avanti'
                        Indietro.setVisibility(View.VISIBLE);//il bottone 'Indietro' diventa visibile
                        Indietro.setOnClickListener(this);
                        /* aggiorno i poi da visualizzare */
                        pois_disp = null;
                        pois_disp = new ArrayList<Poi>();
                        /* di nuovo: se ci sono + di 5 poi */
                        if(Pois.size()>(count_indice_pois_avanti+5)){
                                for(int i=count_indice_pois_avanti;i<(count_indice_pois_avanti+5);i++){
                                pois_disp.add(Pois.get(i));
                                }
                        p_adapter.items = pois_disp;
                        p_adapter.notifyDataSetChanged();
                        count_indice_pois_avanti=(count_indice_pois_avanti+5);
                        }
                        else{//ci sono rimasti di meno di 5
                                for(int i=count_indice_pois_avanti;i<=Pois.size()-1;i++){
                                        pois_disp.add(Pois.get(i));
                                }
                                /*int index = (5-pois_disp.size());
                                for(int j=0; j<=index;j++){//quelli che mancano a 5
                                        pois_disp.add(Pois.get(j));
                                }*/

                                p_adapter.items = pois_disp;
                                p_adapter.notifyDataSetChanged();
                                count_indice_pois_avanti = Pois.size()-1;
                       
                        }
        }
        else if(v == Indietro){
                count_indice_pois_indietro=(count_indice_pois_avanti-10);
                pois_disp = null;
                pois_disp = new ArrayList<Poi>();
               
                if(count_indice_pois_indietro>5){//clicca su Indietro, se ci sono + di 5 POI allora devo fare visualizzare ancora il pulsante Indietro, altrimenti no
                       
                        for(int i=(count_indice_pois_indietro);i<count_indice_pois_avanti;i++){
                                pois_disp.add(Pois.get(i));
                        }      
                        p_adapter.items = pois_disp;
                        p_adapter.notifyDataSetChanged();
                       
                }
                else{
                        Indietro.setVisibility(View.INVISIBLE);
               
                        for(int i=(count_indice_pois_indietro);i<count_indice_pois_avanti;i++){
                                pois_disp.add(Pois.get(i));
                        }      
                        p_adapter.items = pois_disp;
                        p_adapter.notifyDataSetChanged();
                }
                count_indice_pois_avanti=count_indice_pois_avanti-5;
        }
        else if(v == Aggiungi){
               
        }
        else if(v == Mappa){
               
        }
       
}

public static double arrotondaPerEccesso(double valore, int cifreDecimali) {
    double fattore = Math.pow(10, cifreDecimali);
    return Math.ceil(valore * fattore) / fattore;
}


}
   

i due file xml di layout sono i seguenti:
Codice (XML): [Seleziona]
<?xml version="1.0" encoding="utf-8"?>
<TableLayout xmlns:android="http://schemas.android.com/apk/res/android"
   android:layout_width="fill_parent"
   android:layout_height="fill_parent"
   android:stretchColumns="2">

        <TextView
                android:text="Lista POI:"
                android:id="@+id/r0c0"
           android:padding="3dip" />
         
           
       <ListView
               
                        android:id="@android:id/list"
                        android:drawSelectorOnTop="false"
                        android:padding="3dip"
        />
         
   
   
       
    <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent">
   
        <Button android:text="Mappa"
                        android:id="@+id/bottoneMappa"
                        android:layout_width="wrap_content"
                        android:layout_height="wrap_content"
                        >
                </Button>
   
                <Button android:text="Aggiungi"
                        android:id="@+id/bottoneAggiungi"
                        android:layout_width="wrap_content"
                        android:layout_height="wrap_content"
                        android:layout_toRightOf="@+id/bottoneMappa"
                        android:layout_alignTop="@+id/bottoneMappa">
                </Button>
               
               
   
        <Button android:text="Avanti"
                        android:id="@+id/bottoneAvanti"
                        android:layout_width="wrap_content"
                        android:layout_height="wrap_content"
                        android:layout_alignTop="@+id/bottoneAggiungi"
                        android:layout_alignParentRight="true">
                </Button>
               
                <Button android:text="Indietro"
                        android:id="@+id/bottoneIndietro"
                        android:layout_width="wrap_content"
                        android:layout_height="wrap_content"
                        android:layout_toLeftOf="@+id/bottoneAvanti"
                        android:layout_alignTop="@+id/bottoneAvanti"
                        >
                </Button>
                 
         </RelativeLayout>

</TableLayout>


e il layout di ogni riga:
Codice (XML): [Seleziona]
<TableLayout xmlns:android="http://schemas.android.com/apk/res/android"
   android:layout_width="fill_parent"
   android:layout_height="fill_parent"
   android:stretchColumns="2">

        <TableRow>
        <RelativeLayout
                xmlns:android="http://schemas.android.com/apk/res/android"
                android:layout_width="fill_parent"
                android:layout_height="fill_parent">
                        <!-- riga x colonna 0-->
                <ImageView
                        android:id="@+id/imm_1"
                        android:baselineAlignBottom="true"
                        android:layout_height="70dip"
                        android:layout_width="60dip"
                        android:layout_column="0" />
               
                        <!-- riga x colonna 1 -->
                <TextView
                        android:text="nome poi"
                        android:id="@+id/poi_1"
                        android:layout_column="1"
                        android:layout_width="120dip"
                                android:layout_height="70dip"
                                android:gravity="center"
                                android:layout_toRightOf="@+id/imm_1"/>
           
                         <!-- riga x colonna 2 -->
                <TextView
                        android:text="distanza"
                        android:id="@+id/dist_1"
                        android:layout_column="2"
                        android:layout_width="120dip"
                                android:layout_height="70dip"
                android:gravity="center"
                android:layout_toRightOf="@+id/poi_1"/>
        </RelativeLayout>
    </TableRow>
   
</TableLayout>

Qualcuno mi sà dire cosa c'è che non va???
Grazie in anticipo...

Offline bradipao

  • Moderatore globale
  • Utente storico
  • *****
  • Post: 4043
  • keep it simple
  • Respect: +567
    • Github
    • Google+
    • bradipao
    • Mostra profilo
  • Dispositivo Android:
    Nexus 5
  • Play Store ID:
    Bradipao
  • Sistema operativo:
    W7
Re:adapter -- metodo getView() che restituisce errore di IndexOutOfBound
« Risposta #1 il: 24 Maggio 2011, 18:02:07 CEST »
+1
Io eviterei di distruggere buttare via ogni volta l'arraylist per farne uno nuovo, anche perchè poi dovresti rifare anche l'adapter. Più semplice svuotarlo, aggiornarno e notificare il cambio dati all'adapter.

Sostituisci:
Codice (Java): [Seleziona]
pois_disp = null;
pois_disp = new ArrayList<Poi>();
Con:
Codice (Java): [Seleziona]
pois_disp.clear();
E rimuovi:
Codice (Java): [Seleziona]
p_adapter.items = pois_disp;
Ovviamente cambiando in modo analogo i vari punti in cui ridefinisci la base dati.
NON rispondo a domande nei messaggi privati
Bradipao @ Play Store

Offline pablo86

  • Nuovo arrivato
  • *
  • Post: 8
  • Respect: 0
    • Mostra profilo
  • Dispositivo Android:
    AVD: HVGA
  • Sistema operativo:
    Windows XP
Re:adapter -- metodo getView() che restituisce errore di IndexOutOfBound
« Risposta #2 il: 24 Maggio 2011, 21:21:38 CEST »
0
Ciao,

Grazie del tuo suggerimento.
In questo modo non ho più il mio problema e mi visualizza correttamente anche gli ultimi elementi.

Solo che adesso così facendo quando clicco su avanti mi visualizza i 5 elemti successivi, mentre quando clicco su indietro non mi fa visualizzare solo i 5 precedenti ma tutti e 10 gli elementi insieme.

Qualche suggermento per risolvere quest'ultimo inconveniente?

Grazie ancora.

Offline bradipao

  • Moderatore globale
  • Utente storico
  • *****
  • Post: 4043
  • keep it simple
  • Respect: +567
    • Github
    • Google+
    • bradipao
    • Mostra profilo
  • Dispositivo Android:
    Nexus 5
  • Play Store ID:
    Bradipao
  • Sistema operativo:
    W7
Re:adapter -- metodo getView() che restituisce errore di IndexOutOfBound
« Risposta #3 il: 24 Maggio 2011, 21:29:22 CEST »
+1
Qualche suggermento per risolvere quest'ultimo inconveniente?

Lo hai fatto il clear anche quando torni indietro?
NON rispondo a domande nei messaggi privati
Bradipao @ Play Store

Offline pablo86

  • Nuovo arrivato
  • *
  • Post: 8
  • Respect: 0
    • Mostra profilo
  • Dispositivo Android:
    AVD: HVGA
  • Sistema operativo:
    Windows XP
Re:adapter -- metodo getView() che restituisce errore di IndexOutOfBound
« Risposta #4 il: 24 Maggio 2011, 21:31:10 CEST »
0
Grazie,

Ho risolto... ho corretto l'aggiornamento del valore dell'indice.

Offline bradipao

  • Moderatore globale
  • Utente storico
  • *****
  • Post: 4043
  • keep it simple
  • Respect: +567
    • Github
    • Google+
    • bradipao
    • Mostra profilo
  • Dispositivo Android:
    Nexus 5
  • Play Store ID:
    Bradipao
  • Sistema operativo:
    W7
Re:adapter -- metodo getView() che restituisce errore di IndexOutOfBound
« Risposta #5 il: 24 Maggio 2011, 22:07:59 CEST »
0
In generale (vale per tutti i thread di tutti gli utenti), quando un post ti è stato di aiuto, dai un CLIC sul tastino ;-)
NON rispondo a domande nei messaggi privati
Bradipao @ Play Store