2 Arrays nella ListView

di Anonimizzato12301 il
25 risposte
Voglio popolare una ListView con 2 Array. Il primo array è visualizzato nella prima colonna della Listview; il secondo Array, nella seconda colonna, che viene estratto dal database e deve posizionarsi sulla stessa riga. (tipo un'agenda)
Ecco quello che ho fatto finora, e questo è l'errore che ho.

03-20 23:12:00.918    8517-8517/com.poliveira.apps.materialtests E/AndroidRuntime? FATAL EXCEPTION: main
java.lang.IndexOutOfBoundsException: Invalid index 0, size is 0
        at java.util.ArrayList.throwIndexOutOfBoundsException(ArrayList.java:251)
        at java.util.ArrayList.get(ArrayList.java:304)
        at appuntamenti.Elenco_Fragment$1.getView(Elenco_Fragment.java:164)
        at android.widget.AbsListView.obtainView(AbsListView.java:2696)
        at android.widget.ListView.measureHeightOfChildren(ListView.java:1253)
        at android.widget.ListView.onMeasure(ListView.java:1165)
        at android.view.View.measure(View.java:16271)
        at android.widget.RelativeLayout.measureChildHorizontal(RelativeLayout.java:681)
        at android.widget.RelativeLayout.onMeasure(RelativeLayout.java:461)
        at android.view.View.measure(View.java:16271)
        at android.widget.RelativeLayout.measureChildHorizontal(RelativeLayout.java:681)
        at android.widget.RelativeLayout.onMeasure(RelativeLayout.java:461)
        at android.view.View.measure(View.java:16271)
        at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:4945)
        at android.widget.FrameLayout.onMeasure(FrameLayout.java:310)
        at android.view.View.measure(View.java:16271)
        at android.support.v4.widget.DrawerLayout.onMeasure(DrawerLayout.java:851)
        at android.view.View.measure(View.java:16271)
        at android.widget.RelativeLayout.measureChildHorizontal(RelativeLayout.java:681)
        at android.widget.RelativeLayout.onMeasure(RelativeLayout.java:461)
        at android.view.View.measure(View.java:16271)
        at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:4945)
        at android.widget.FrameLayout.onMeasure(FrameLayout.java:310)
        at android.view.View.measure(View.java:16271)
        at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:4945)
        at android.widget.LinearLayout.measureChildBeforeLayout(LinearLayout.java:1410)
        at android.widget.LinearLayout.measureVertical(LinearLayout.java:695)
        at android.widget.LinearLayout.onMeasure(LinearLayout.java:588)
        at android.view.View.measure(View.java:16271)
        at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:4945)
        at android.widget.FrameLayout.onMeasure(FrameLayout.java:310)
        at android.view.View.measure(View.java:16271)
        at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:4945)
        at android.widget.LinearLayout.measureChildBeforeLayout(LinearLayout.java:1410)
        at android.widget.LinearLayout.measureVertical(LinearLayout.java:695)
        at android.widget.LinearLayout.onMeasure(LinearLayout.java:588)
        at android.view.View.measure(View.java:16271)
        at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:4945)
        at android.widget.FrameLayout.onMeasure(FrameLayout.java:310)
        at com.android.internal.policy.impl.PhoneWindow$DecorView.onMeasure(PhoneWindow.java:2501)
        at android.view.View.measure(View.java:16271)
        at android.view.ViewRootImpl.performMeasure(ViewRootImpl.java:2182)
        at android.view.ViewRootImpl.measureHierarchy(ViewRootImpl.java:1330)
        at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:1541)
        at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1227)
        at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:4995)
        at android.view.Choreographer$CallbackRecord.run(Choreographer.java:791)
        at android.view.Choreographer.doCallbacks(Choreographer.java:591)
        at android.view.Choreographer.doFrame(Choreographer.java:561)
        at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:777)
        at android.os.Handler.handleCallback(Handler.java:725)
        at android.os.Handler.dispatchMessage(Handler.java:92)
        at android.os.Looper.loop(Looper.java:175)
        at android.app.ActivityThread.main(ActivityThread.java:5279)
        at java.lang.reflect.Method.invokeNative(Native Method)
        at java.lang.reflect.Method.invoke(Method.java:511)
        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1102)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:869)
        at dalvik.system.NativeStart.main(Native Method)


static final String[] orari = new String[] {
        "8:00", "8:30", "9:00", "9:30", "10:00",
        "10:30", "11:00", "11:30", "12:00", "12:30",
        "13:00", "13:30", "14:00", "14:30", "15:00",
        "15:30", "16:00", "16:30", "17:00", "17:30",
        "18:00", "18:30", "19:00", "19:30", "20:00"};

private void prova(){
    SQLiteDatabase db = new DatabaseHelper(getActivity()).getReadableDatabase();
    final List<Dettaglio> dettagli = new ArrayList<Dettaglio>();

    for (int i=1; i<=orari.length; i++){
String tabella_op = "SELECT ........";
        Cursor cur = db.rawQuery(tabella_op, null);
        while (cur.moveToNext()) {
            Dettaglio d = new Dettaglio();
            d.id = cur.getString(0);
            d.hour= cur.getString(1);//esempio 1 solo record in memoria   10:30
            d.nome = cur.getString(2);
            d.cognome = cur.getString(3);
            dettagli.add(d);

        }
    cur.close();
} 
db.close();
ListAdapter adapter = new ArrayAdapter<String>(getActivity(), R.layout.appuntamenti_row, R.id.timeText, orari){

        @Override
        public View getView(int position, View convertView, ViewGroup parent) {
            View row = super.getView(position, convertView, parent);

            String ore = orari[position];
            TextView tvHour = (TextView) row.findViewById(R.id.timeText);
            tvHour.setText(ore);

            TextView tvA;
            tvAppuntamento = (TextView) row.findViewById(R.id.eventText);
            Dettaglio d = dettagli.get(position);
            tvA.setText(d.nome+" "+d.cognome);



            return row;
        }
    };
    list.setAdapter(adapter);
}

25 Risposte

  • Qual è la riga 164 di Elenco_fragment.java?


    Sent from my iPhone using Tapatalk
  • Sì scusa, è la chiamata alla classe dettaglio


    Dettaglio d = dettagli.get(position);
  • Il codice che hai postato è incompleto, quindi non si riesce a vedere l'intero flusso, comunque è evidente che la lista "dettagli" sia riempita DOPO aver impostato l'adapter. Di conseguenza ti viene lanciata un'eccezione sugli indici della lista quando provi a recuperarne gli elementi


    Sent from my iPhone using Tapatalk
  • Hai suggerimenti?
  • Senza sapere com'è il resto del codice non è immediato rispondere, però il problema deriva dal fatto che cerchi di riempire una lista ma non hai i dati con cui popolarla.. Quindi potresti ritardare il popolamento della lista finché non hai a disposizione i dati, oppure di default android prevede un modo per mostrare una View alternativa quando la ListView è vuota: semplicemente nel tuo file di layout xml devi mettere una view con android:id="@android:id/empty"
  • Ciò che manca al codice è solo la query (che funziona bene). Cerco di spiegare meglio: l'Array orari deve essere sempre visualizzato, quindi la Listview deve avere sempre 25 righe (numero totale degli orari). Quindi prelevo i dati dal db e voglio posizionare i records della tabella a fianco degli orari, come se fosse un'agenda, per cui non è detto che dettagli ha sempre 25 colonne, come in questo esempio:

    8:00
    8:30 nome e cognome dal db
    9:00
    9:30
    10:00
    10:30 nome e cognome dal db
    11:00
    11:30
    ecc..

    forse non è il modo giusto per ricreare un'agenda?
  • Beh come modalità può andare bene, però come ti dicevo probabilmente c'è un errore coi "tempi".. Devi fare in modo che l'adapter sia settato dopo che l'array dettagli sia riempito
  • È qui il dilemma....come faccio? in rete non ho trovato esempi che possano aiutarmi.
  • In realtà il codice mi sembra giusto per questo aspetto. L'unica cosa è che magari la query non restituisce nessun risultato, quindi la lista potrebbe essere vuota. Inoltre in base al codice, se tu hai 1 solo "dettaglio" ti salterà fuori sempre un'eccezione visto che la variabile "position" varia fra 0 e il numero di ore-1
  • Si, se la query non restituisce nessun risultato, il mio scopo è quello di visualizzare ugualmente l'Array "orari". Per capire cosa voglio fare basta pensare ad un'Agenda, in cui la prima colonna della Lista ha le ore del giorno e la colonna di destra ha gli impegni.....

    Avevo pensato ad una GridView ma non sembra adatta ad ottenere questo...Che dici?
  • Mah gridview o listview cambia poco a livello di gestione, è più che altro una scelta estetica.. Il problema che devi affrontare è come associare uno o più dettagli ad una fascia oraria. Attualmente per ogni fascia gestisci 1 e 1 solo dettaglio (nel senso che gestisce i dettagli in base alla posizione nell'array, la quale è strettamente associata alla fascia oraria). Come conseguenza se il numero di dettagli è diverso dal numero di ore allora l'app crasha o non mostra tutti i dati
  • Spiegato perfettamente...hai un modo da suggerire?
  • Il modo più semplice è quello di effettuare una query per ogni fascia oraria e riempire di conseguenza le celle della lista.. L'unico inconveniente è che è un po' inefficiente!
  • Ok, ho fatto una prova passando alla query ogni riga dell'Array "orari", ottengo però una eccezione dal db perchè a quell'ora non ci sono records...quindi in pratica stesso errore di prima.
    questo è il metodo:
    
    private void prova(){
            SQLiteDatabase db = new DatabaseHelper(getActivity()).getReadableDatabase();
            final List<Dettaglio> dettagli = new ArrayList<Dettaglio>();
    
            for (int i=1; i<=orari.length; i++){
    
    String tabella_op = "SELECT m.id_cliente, m.ora, c.nome, c.cognome FROM Movimenti m LEFT JOIN Clienti" +
            " c ON (m.id_cliente = c._id) AND ora LIKE "+orari[i]+"";
                Cursor cur = db.rawQuery(tabella_op, null);
                while (cur.moveToNext()) {
                    Dettaglio d = new Dettaglio();
                    d.id = cur.getString(0);
                    d.ora = cur.getString(1);
                    d.nome = cur.getString(2);
                    d.cognome = cur.getString(3);
                    dettagli.add(d);
    
                }
            cur.close();
        }
        db.close();
    
            ListAdapter adapter = new ArrayAdapter<String>(getActivity(), R.layout.appuntamenti_row, R.id.timeText, orari){
    
                @Override
                public View getView(int position, View convertView, ViewGroup parent) {
                    View row = super.getView(position, convertView, parent);
    
                    String ore = orari[position];
                    TextView tvMonth = (TextView) row.findViewById(R.id.timeText);
                    tvMonth.setText(ore);
    
                    TextView tvAppuntamento;
                    tvAppuntamento = (TextView) row.findViewById(R.id.eventText);
                    Dettaglio d = dettagli.get(position);
                    tvAppuntamento.setText(d.nome+" "+d.cognome);
    
                    list.setOnItemClickListener(new OnItemClickListener(){
                        @Override
                        public void onItemClick(AdapterView<?> parent, View view,int position, long id) {
                            TextView tvMonth = (TextView) view.findViewById(R.id.timeText);
                            String item = tvMonth.getText().toString();
                            Toast.makeText(getActivity().getBaseContext(), item, Toast.LENGTH_LONG).show();        }
                    });
                    return row;
                }
            };
            list.setAdapter(adapter);
        }
    

    Process: com.poliveira.apps.materialtests, PID: 2357
    android.database.sqlite.SQLiteException: near ":30": syntax error (code 1): , while compiling: SELECT m.id_cliente, m.ora, c.nome, c.cognome FROM Movimenti m LEFT JOIN Clienti c ON (m.id_cliente = c._id) AND ora LIKE 8:30
    at android.database.sqlite.SQLiteConnection.nativePrepareStatement(Native Method)
    at android.database.sqlite.SQLiteConnection.acquirePreparedStatement(SQLiteConnection.java:889)
    at android.database.sqlite.SQLiteConnection.prepare(SQLiteConnection.java:500)
    at android.database.sqlite.SQLiteSession.prepare(SQLiteSession.java:588)
    at android.database.sqlite.SQLiteProgram.<init>(SQLiteProgram.java:58)
    at android.database.sqlite.SQLiteQuery.<init>(SQLiteQuery.java:37)
    at android.database.sqlite.SQLiteDirectCursorDriver.query(SQLiteDirectCursorDriver.java:44)
    at android.database.sqlite.SQLiteDatabase.rawQueryWithFactory(SQLiteDatabase.java:1316)
    at android.database.sqlite.SQLiteDatabase.rawQuery(SQLiteDatabase.java:1255)
    at appuntamenti.Elenco_Fragment.prova(Elenco_Fragment.java:138)
    at appuntamenti.Elenco_Fragment.onCreateView(Elenco_Fragment.java:125)
    at android.app.Fragment.performCreateView(Fragment.java:2053)
    at android.app.FragmentManagerImpl.moveToState(FragmentManager.java:894)
    at android.app.FragmentManagerImpl.moveToState(FragmentManager.java:1067)
    at android.app.BackStackRecord.run(BackStackRecord.java:833)
    at android.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:1452)
    at android.app.FragmentManagerImpl$1.run(FragmentManager.java:447)
    at android.os.Handler.handleCallback(Handler.java:739)
    at android.os.Handler.dispatchMessage(Handler.java:95)
    at android.os.Looper.loop(Looper.java:135)
    at android.app.ActivityThread.main(ActivityThread.java:5221)
    at java.lang.reflect.Method.invoke(Native Method)
    at java.lang.reflect.Method.invoke(Method.java:372)
    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:899)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:694)

Devi accedere o registrarti per scrivere nel forum
25 risposte