2 Arrays nella ListView

di Anonimizzato12301 il
25 risposte

25 Risposte - Pagina 2

  • No, non è lo stesso errore di prima, guarda il log! 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
  • Dunque, ho modificato il ciclo for prima della query, passando ad una stringa il contenuto dell'Array "orari". L'app si avvia e non crasha, ma la colonna e null, nonostante per prova ho inserito un record corrispondente alle ore "10:30", quindi "dettagli", "d.ora" contiene un record "10:30"
    
     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 prova = ""+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 "+prova+"";
                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);
        }
    
    
  • Nella clausola "like" dovresti mettere gli apici intorno alla parola, forse è per quello che non va!
  • Ho appena rimesso mano al metodo...ora nessun errore ma la ListView è vuota. Il mio scopo, come dicevo, è quello di visualizzare ugualmente l'Array "orari", anche se nel db non ci sono records.

    codice completo:
    
    
    private void prova(){
            SQLiteDatabase db = new DatabaseHelper(getActivity()).getReadableDatabase();
            final List<Dettaglio> dettagli = new ArrayList<appuntamenti.Elenco_appuntamentiFragment.Dettaglio>(25);
    
            for (int i=1; i<=orari.length; i++){
                    String prova = ""+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 '"+prova+"'";
                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<Dettaglio>(getActivity(), R.layout.appuntamenti_row, R.id.timeText, dettagli){
    
                @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);
        }
    
    
        private class Dettaglio {
            String id;
            String nome;
            String cognome;
            String ora;
        }
    
    
  • Il punto è che nell'adapter devi mettere l'array di orari, poiché è il dato principale che vuoi visualizzare. Poi per ogni orario dovrai fare la query ed eventualmente aggiungere il dettaglio alla riga dell'orario
  • Allora, passo all'adapter l'array "orari", quindi, per ogni query passo ogni dato dell'array "orari".
    Ricevo errore
     java.lang.IndexOutOfBoundsException: Invalid index 0, size is 0
                at java.util.ArrayList.throwIndexOutOfBoundsException(ArrayList.java:255)
    la parte incriminata è quando richiamo i dati dalla classe "Dettaglio", queste righe:
     Dettaglio d = dettagli.get(position);
                    tvAppuntamento.setText(d.nome + " " + d.cognome);
    non dovrebbe dare errore, ho fatto in passato una cosa simile con i mesi dell'anno e cioè, una lista dei mesi dell'anno, e per ogni mese faccio una query che raggruppa i dati in base al mese corrispondente, guarda questo codice, funziona perfettamente anche se i dati della classe "Dettaglio" sono vuoti..

    il metodo vecchio con i mesi dell'anno:
    
    private void showDetails(String anno){
    		SQLiteDatabase db = new MyHelper(this).getReadableDatabase();
    		final List<Dettaglio> dettagli = new ArrayList<Activity.Dettaglio>(12);
    		
    		for (int i=1; i<=12; i++){
    			String mese;
    			if (i<10){
    				mese = "0"+i;
    			} else {
    				mese = ""+i;
    			}
    			String sql = "SELECT SUM(data1), SUM(data2), SUM(data1)-SUM(data2) FROM Table WHERE data LIKE '"+anno+"-"+mese+"%'";
    			Cursor c = db.rawQuery(sql, null);
    			
    			while (c.moveToNext()){
    				Dettaglio d = new Dettaglio();
    				d.data1 = c.getFloat(0);
    				d.data2 = c.getFloat(1);
    				d.differenza = c.getFloat(2);
    				
    				dettagli.add(d);
    			}
    			c.close();
    		}
    		
    		db.close();
    		
    		ListAdapter adapter = new ArrayAdapter<Dettaglio>(this, R.layout.dettaglio_row, R.id.tv_mese, dettagli){
    			
    			@Override
    			public View getView(int position, View convertView, ViewGroup parent) {
    				View row = super.getView(position, convertView, parent);
    								
    				String month = new DateFormatSymbols(Locale.getDefault()).getMonths()[position];
    				TextView tvMonth = (TextView) row.findViewById(R.id.tv_mese);
    				tvMonth.setText(month);
    				
    	
    				TextView tvData1, tvData2, tvDiffrenza;
                    tvData1 = (TextView) row.findViewById(R.id.tv_1);
                    tvData1.setTextColor(Color.GREEN);
    
                    tvData2 = (TextView) row.findViewById(R.id.tv_2);
                    tvData2.setTextColor(Color.RED);
    
                    tvDiffrenza = (TextView) row.findViewById(R.id.tv_3);
                    tvDiffrenza.setTextColor(Color.YELLOW);
    				
    				Dettaglio d = dettagli.get(position);
                    tvData1.setText(d.data1+"");
                    tvData2.setText(d.data2+"");
                    tvDiffrenza.setText(d.differenza+"");
    				return row;
    			}
    		};
    		lista.setAdapter(adapter);
    	}
    


    il codice completo che dà errore:
    
    private void prova() {
            SQLiteDatabase db = new DatabaseHelper(getActivity()).getReadableDatabase();
            final List<Dettaglio> dettagli = new ArrayList<appuntamenti.Elenco_appuntamentiFragment.Dettaglio>(25);
    
            for (int i = 1; i <= orari.length; i++) {
                String prova = "" + 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 '" + prova + "'";
                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);
        }
    
        private class Dettaglio {
            String id;
            String nome;
            String cognome;
            String ora;
        }
    
    sono praticamente uguali....devo uscirne!!!!!
  • Il punto è che continui a "traslare" l'errore, senza correggerlo: l'array "dettagli" per qualche motivo è vuoto (es: la query non restituisce nessun risultato); usare la posizione della lista (cioè la variabile "position") come indice dell'array "dettagli" è sbagliato, perché l'elemento principale della lista è la fascia oraria, e non c'è una relazione 1 ad 1 fra fascia oraria ed appuntamento (cioè per una fascia oraria potresti avere 0, 1 oppure N appuntamenti, non puoi saperlo a priori).

    Quello che intendevo io è qualcosa del genere:
    
    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        ...
        qua ottieni la fascia oraria (es: 9:00 - 9:30)
        ...
        qua fai la query ottenendo gli appuntamenti in quella fascia oraria
        ...
        qua riempi la TextView
    }              
    
    In questo modo dell'array dettagli puoi farne a meno, in quanto recuperi i vari appuntamenti a mano a mano che riempi la lista. Lo svantaggio è l'inefficienza (ogni volta che fai lo scroll della lista devi rifare le query per le righe che diventano visibili, quindi magari potresti implementare una forma di caching dei risultati)
  • È una soluzione ma lo scroll ovviamente è terribile.
    domanda finale....tu come faresti se dovessi fare una sorta di agenda??
  • Mah penso che farei una sorta di lista con tutti gli impegni (ordinata in ordine crescente, per velocizzare le ricerche future). Dopodiché per ogni cella della lista bisogna andarsi a cercare gli impegni di una certa fascia oraria e popolare la lista di conseguenza. Anche la soluzione del "mi faccio una query per ogni riga" potrebbe andare bene, a patto di implementare un meccanismo di caching, in modo da evitare di doversi andare a rifare la query ogni volta (cosa sicuramente più difficile)
  • Ho convertito l'Array
    orari
    in una lista, poi lo passo alla query. Funziona, ma se nel db non ci sono dati
    Dettaglio d = dettagli.get(position); 
    và in
    IndexOutOfBoundsException
    .

    E' possibile aggirare il problema?


    
    private void prova() {
            //converto il calendario per la query
            SimpleDateFormat simpleFormat = new SimpleDateFormat("yyyy-MM-dd");
            String strDate = simpleFormat.format(calendar.getTime());
    
            final List<Dettaglio> dettagli = new ArrayList<appuntamenti.Elenco_appuntamentiFragment.Dettaglio>(25);
            SQLiteDatabase db = new DatabaseHelper(getActivity()).getReadableDatabase();
            // converto array a lista
            List<String> lList = Arrays.asList(orari);
            // iterator loop
            Iterator<String> iterator = lList.iterator();
            while (iterator.hasNext()) {
                String orari_array = (iterator.next());
                String tabella_op = "SELECT m.id_cliente, m.data, m.ora, c.nome, c.cognome FROM Movimenti m LEFT JOIN Clienti" +
                        " c ON (m.id_cliente = c._id) AND m.ora LIKE '" + orari_array + "' AND m.data LIKE '" + strDate + "'";
                Cursor cur = db.rawQuery(tabella_op, null);
                while (cur.moveToNext()) {
                    Dettaglio d = new Dettaglio();
                    d.id = cur.getString(0);
                    d.data = cur.getString(1);
                    d.ora = cur.getString(2);
                    d.nome = (cur.getString(3) != null) ? cur.getString(3) : "";
                    d.cognome = (cur.getString(4) != null) ? cur.getString(4) : "";
                    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);
    
                    TextView tvAppuntamento;
                    tvAppuntamento = (TextView) row.findViewById(R.id.eventText);
                    Dettaglio d = dettagli.get(position);
                    tvAppuntamento.setText(d.nome + " " + d.cognome);
    
                    String ore = orari[position];
                    TextView tvMonth = (TextView) row.findViewById(R.id.timeText);
                    tvMonth.setText(ore);
    
                    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);
        }
    
  • Quello che sto cercando di dirti da qualche post è che la riga
    Dettaglio d = dettagli.get(position);
    non solo è sbagliata, ma non ha proprio senso. Tu vai a prendere da "dettagli" l'elemento in posizione "position", ma non c'è alcuna relazione fra la posizione (che, se mai, è correlata alla fascia oraria) e il dettaglio, tant'è che in una fascia oraria potresti avere 0, 1 oppure mille impegni. Di conseguenza la modifica che hai fatto su "orari" è superflua, potevi lasciare tranquillamente un array.
    Quello che devi fare è: per ogni cella della ListView (--> nel metodo getView) andarti a scandire la lista dei dettagli per vedere se devi mostrare qualcosa sulla lista oppure no
Devi accedere o registrarti per scrivere nel forum
25 risposte