Autore Topic: Listview con Database e Searchbox  (Letto 1734 volte)

Offline Antonio

  • Nuovo arrivato
  • *
  • Post: 7
  • Respect: 0
    • Mostra profilo
Listview con Database e Searchbox
« il: 10 Gennaio 2011, 12:38:48 CET »
0
Ciao a tutti... Sono ancora alle prime armi nella programmazione per android, sto seguendo ancora diversi tutorial per imparare un minimo del mondo android...

Seguendo diversi tutorial, ho implementato un database sql ed una searchbox che ricerca al suo interno e mi mostra il tutto in una listview che mi permette di cliccare su ogni singolo elemento per vederne il dettaglio... Però adesso, alla fine di tutto, mi accorgo che per rendere il tutto più semplice, sarebbe meglio che la listview invece di partire vuota e riempirsi dopo il cerca, dovrebbe partire piena di tutti gli elementi del database e modificarsi in seguito alla ricerca... Dico già che cerca e click funzionano tutti... Lì non ci sono problemi... Il mio unico problema è la listview...

Se avessi i dati stringati all'interno del codice saprei sfruttarli per inserirli dentro alla listview semplicemente con:

Codice (Java): [Seleziona]
lv1=(ListView)findViewById(R.id.ListView01);
lv1.setAdapter(new ArrayAdapter<String>(this,android.R.layout.simple_list_item , lv_arr));

Cioè settando il layout impostato per la listview e lv_arr definito sopra come:

Codice (Java): [Seleziona]
private String lv_arr[]={"Mario","Antonio","Davide","Lisa","Marta","Marilena",};
Però ora che ho il database mi sono perso... Vi posto il codice del tutorial che comunque è identico al mio(ho cambiato solo gli elementi ed utilizzato l'italiano come lingua base):

Codice (Java): [Seleziona]
public class EmployeeList extends Activity {
       
        protected EditText searchText;
        protected SQLiteDatabase db;
        protected Cursor cursor;
        protected ListAdapter adapter;
        protected ListView employeeList;
       
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        db = (new DatabaseHelper(this)).getWritableDatabase();
        searchText = (EditText) findViewById (R.id.searchText);
        employeeList = (ListView) findViewById (R.id.list);
    }
   
    public void search(View view) {
        // || is the concatenation operation in SQLite
                cursor = db.rawQuery("SELECT _id, firstName, lastName, title FROM employee WHERE firstName || ' ' || lastName LIKE ?",
                                                new String[]{"%" + searchText.getText().toString() + "%"});
                adapter = new SimpleCursorAdapter(
                                this,
                                R.layout.employee_list_item,
                                cursor,
                                new String[] {"firstName", "lastName", "title"},
                                new int[] {R.id.firstName, R.id.lastName, R.id.title});
                employeeList.setAdapter(adapter);
    }
   
}

Come posso settare il codice? Non sono riuscito a trovare esempi o tutorial utili per me... Io avevo pensato di aggiungere un employeeList.setAdapter("codice") dentro all'onCreate... Però non so come fare per via del database...


Per correttezza nei confronti del creatore del tutorial, questo è il link del suo tutorial: qui

Offline Nicola_D

  • Moderatore
  • Utente storico
  • *****
  • Post: 2479
  • SBAGLIATO!
  • Respect: +323
    • Github
    • Google+
    • nicoladorigatti
    • Mostra profilo
  • Dispositivo Android:
    Nexus 6p, Nexus 4, Nexus S, Nexus 7(2012)
  • Sistema operativo:
    Windows 7
Re:Listview con Database e Searchbox
« Risposta #1 il: 10 Gennaio 2011, 13:20:09 CET »
+1
semplicemente,nell'oncreate vai a prendere tutti gli elementi del database,senza where clause e li mostri.
Codice (Java): [Seleziona]
public void allElements(View view) {
     
                cursor = db.rawQuery("SELECT _id, firstName, lastName, title FROM employee , null});
                adapter = new SimpleCursorAdapter(
                                this,
                                R.layout.employee_list_item,
                                cursor,
                                new String[] {"
firstName", "lastName", "title"},
                                new int[] {R.id.firstName, R.id.lastName, R.id.title});
                employeeList.setAdapter(adapter);
    }
ad ogni modo, avevo fatto un tutorial con gli update della listview, [facile] Aggiornare ListView popolata da un cursor + download e parsing JSON - Android Developers Italia

senza rifare l'adapter, cambi il cursor all'adapter. Eviti inizializzazioni inutili e semplifichi il lavoro!

Codice (Java): [Seleziona]
private void updateListView() {
                TextView titleTv = (TextView) findViewById(R.id.dbTv);
                db.open();
                c = db.fetchPiloti(); // query
                startManagingCursor(c);
                adapter.changeCursor(c);
                adapter.notifyDataSetChanged();
                int nPiloti = db.countRecords(Variables.PilotiMD.PILOTI_TABLE);
                titleTv.setText("Database F1Db\n\tTabella " + Variables.PilotiMD.PILOTI_TABLE + " , n° di Record: " + nPiloti + "\n");
                db.close();
        }
IMPORTANTE:NON RISPONDO A PROBLEMI VIA MESSAGGIO PRIVATO
LOGCAT: Non sai cos'è? -> Android Debug Bridge | Android Developers
               Dov'è in Eclipse? -> Window -> Open Prospective -> DDMS e guarda in basso!
[Obbligatorio] Logcat, questo sconosciuto! (Gruppo AndDev.it LOGTFO) - Android Developers Italia

Offline Antonio

  • Nuovo arrivato
  • *
  • Post: 7
  • Respect: 0
    • Mostra profilo
Re:Listview con Database e Searchbox
« Risposta #2 il: 10 Gennaio 2011, 13:51:51 CET »
0
Purtroppo le mie attuali capacità non mi consento di interpretare il secondo codice... Avevo già visto quel tutorial, ma per quanto sia indicato come [facile], per me al momento tanto facile non è... Comunque io ho così modificato:

Codice (Java): [Seleziona]
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        db = (new DatabaseHelper(this)).getWritableDatabase();
        searchText = (EditText) findViewById (R.id.searchText);
        cursor = db.rawQuery("SELECT _id, firstName, lastName FROM employee" , null});
                adapter = new SimpleCursorAdapter(
                                this,
                                R.layout.employee_list_item,
                                cursor,
                                new String[] {"firstName", "lastName"},
                                new int[] {R.id.firstName, R.id.lastName});
                setListAdapter(adapter);
    }

L'ho testato su macchina virtuale e sembra funzionare... All'avvio mi presenta la lista di tutti i nomi, con sopra la barra di ricerca... Mi permette di cliccare direttamente ogni singolo nome o di cercarne uno specifico e dopo cliccarlo(per un neofita sembra un miracolo)...

Adesso devo solo allungare visibilmente il database, per vedere come si comporta con 30-40 voci inserite...

Solo una cosa... La lista inserita così nel void, mi viene restituita in ordine database, non in ordine alfabetico... E' possibile implementare anche questo oppure devo ricordarmi io di inserire i dati nel database in ordine?

Grazie della celerità  :-)

Offline Nicola_D

  • Moderatore
  • Utente storico
  • *****
  • Post: 2479
  • SBAGLIATO!
  • Respect: +323
    • Github
    • Google+
    • nicoladorigatti
    • Mostra profilo
  • Dispositivo Android:
    Nexus 6p, Nexus 4, Nexus S, Nexus 7(2012)
  • Sistema operativo:
    Windows 7
Re:Listview con Database e Searchbox
« Risposta #3 il: 10 Gennaio 2011, 14:08:39 CET »
+2
Purtroppo le mie attuali capacità non mi consento di interpretare il secondo codice... Avevo già visto quel tutorial, ma per quanto sia indicato come [facile], per me al momento tanto facile non è... Comunque io ho così modificato:

Codice (Java): [Seleziona]
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        db = (new DatabaseHelper(this)).getWritableDatabase();
        searchText = (EditText) findViewById (R.id.searchText);
        cursor = db.rawQuery("SELECT _id, firstName, lastName FROM employee" , null});
                adapter = new SimpleCursorAdapter(
                                this,
                                R.layout.employee_list_item,
                                cursor,
                                new String[] {"firstName", "lastName"},
                                new int[] {R.id.firstName, R.id.lastName});
                setListAdapter(adapter);
    }

L'ho testato su macchina virtuale e sembra funzionare... All'avvio mi presenta la lista di tutti i nomi, con sopra la barra di ricerca... Mi permette di cliccare direttamente ogni singolo nome o di cercarne uno specifico e dopo cliccarlo(per un neofita sembra un miracolo)...

Adesso devo solo allungare visibilmente il database, per vedere come si comporta con 30-40 voci inserite...

Solo una cosa... La lista inserita così nel void, mi viene restituita in ordine database, non in ordine alfabetico... E' possibile implementare anche questo oppure devo ricordarmi io di inserire i dati nel database in ordine?

Grazie della celerità  :-)
allora, per il secondo codice, spiegato velocemente vuol dire modificare il search cosi:
Codice (Java): [Seleziona]
  public void search(View view) {
        // || is the concatenation operation in SQLite
                cursor = db.rawQuery("SELECT _id, firstName, lastName, title FROM employee WHERE firstName || ' ' || lastName LIKE ?",
                                                new String[]{"%" + searchText.getText().toString() + "%"});
adapter.changeCursor(cursor);
                adapter.notifyDataSetChanged();
               
    }

per l'ordinamento devi solo utilizzare l'order by, ORDER BY - Manuale SQL ORDER BY
se vuoi ordinare che ne so, per cognome fai:
Codice (Java): [Seleziona]
   cursor = db.rawQuery("SELECT _id, firstName, lastName, title FROM employee WHERE firstName || ' ' || lastName LIKE ? ORDER BY lastName ASC",
                                                new String[]{"%" + searchText.getText().toString() + "%"});
per ordinare da A-Z, DESC invece di ASC per fare da Z-A.
Spero di aver spiegato bene!
« Ultima modifica: 10 Gennaio 2011, 15:10:05 CET da Nicola_D »
IMPORTANTE:NON RISPONDO A PROBLEMI VIA MESSAGGIO PRIVATO
LOGCAT: Non sai cos'è? -> Android Debug Bridge | Android Developers
               Dov'è in Eclipse? -> Window -> Open Prospective -> DDMS e guarda in basso!
[Obbligatorio] Logcat, questo sconosciuto! (Gruppo AndDev.it LOGTFO) - Android Developers Italia

Offline Antonio

  • Nuovo arrivato
  • *
  • Post: 7
  • Respect: 0
    • Mostra profilo
Re:Listview con Database e Searchbox
« Risposta #4 il: 10 Gennaio 2011, 14:30:39 CET »
0
Adesso ho fatto le modifiche... Tutto bello in ordine... Grazie... Io metterei topic risolto... Per il momento non credo di avere altri problemi... Spero non ne sorgano altri...

 :-)

Offline Antonio

  • Nuovo arrivato
  • *
  • Post: 7
  • Respect: 0
    • Mostra profilo
Re:Listview con Database e Searchbox
« Risposta #5 il: 10 Gennaio 2011, 17:49:59 CET »
0
Mi spiace dover togliere "Topic risolto"... Però mi è nato un nuovo problema... Ho dovuto modificare l'intent... Però adesso quando clicco sul nome da aprire mi da errore... Non vorrei aver commesso qualche errore... Io intanto faccio delle altre prove, però se voi mi aiutate il problema spunta prima... Ecco come ho modificato l'intent:

Codice (Java): [Seleziona]
    public void onListItemClick(ListView parent, View view, int position, long id) {
        Intent intent = new Intent(this, dettagli.class);
        Cursor cursor = (Cursor) adapter.getItem(position);
        intent.putExtra("persone_ID", cursor.getInt(cursor.getColumnIndex("_id")));
        startActivity(intent);
    }

E questo è il nuovo livello:

Codice (Java): [Seleziona]
public class dettagli extends Activity {

    protected TextView personeName;
    protected TextView personeDettagli;
    protected int personeId;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.dettaglipersone);
       
        personeId = getIntent().getIntExtra("persone_ID", 0);
        SQLiteDatabase db = (new DatabaseHelper(this)).getWritableDatabase();
        Cursor cursor = db.rawQuery("SELECT _id, Nome, Cognome FROM databasepersone WHERE _id = ?",
                new String[]{""+personeId});

        if (cursor.getCount() == 1)
        {
            cursor.moveToFirst();
       
            personeName = (TextView) findViewById(R.id.employeeName);
            personeName.setText(cursor.getString(cursor.getColumnIndex("Nome")) + " " + cursor.getString(cursor.getColumnIndex("Cognome")));
   
            personeDettagli = (TextView) findViewById(R.id.dettagli);
            personeDettagli.setText(cursor.getString(cursor.getColumnIndex("Dettagli")));

        }
}
}

Aggiungo il codice del database:

Codice (Java): [Seleziona]
    public void onCreate(SQLiteDatabase db) {

        String sql = "CREATE TABLE IF NOT EXISTS databasepersone (" +
                        "_id INTEGER PRIMARY KEY AUTOINCREMENT, " +
                        "Nome TEXT, " +
                        "Cognome TEXT, " +
                        "Dettagli TEXT)";
        db.execSQL(sql);
       
        ContentValues values = new ContentValues();

        values.put("Nome", "Mario");
        values.put("Cognome", "Rossi");
        values.put("Dettagli", "Dettagli");
        db.insert("databasepersone", "Cognome", values);
       
        values.put("Nome", "Antonio");
        values.put("Cognome", "Rossi");
        values.put("Dettagli", "Dettagli");
        db.insert("databasepersone", "Cognome", values);

    }

Offline Ricky`

  • Amministratore
  • Utente storico
  • *****
  • Post: 3489
  • Respect: +506
    • Github
    • Google+
    • rciovati
    • Mostra profilo
Re:Listview con Database e Searchbox
« Risposta #6 il: 10 Gennaio 2011, 18:04:11 CET »
0
Però adesso quando clicco sul nome da aprire mi da errore... Non vorrei aver commesso qualche errore...

Dovresti postare anche l'output di logcat altrimenti diventa difficile capire l'errore...

Offline Antonio

  • Nuovo arrivato
  • *
  • Post: 7
  • Respect: 0
    • Mostra profilo
Re:Listview con Database e Searchbox
« Risposta #7 il: 10 Gennaio 2011, 19:43:14 CET »
0
Codice: [Seleziona]
01-10 19:40:49.849: ERROR/AndroidRuntime(206): java.lang.RuntimeException: Unable to start activity ComponentInfo{it.antonio.persone/it.antonio.persone.dettagli}: java.lang.IllegalStateException: get field slot from row 0 col -1 failed
01-10 19:40:49.849: ERROR/AndroidRuntime(206):     at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2496)
01-10 19:40:49.849: ERROR/AndroidRuntime(206):     at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2512)
01-10 19:40:49.849: ERROR/AndroidRuntime(206):     at android.app.ActivityThread.access$2200(ActivityThread.java:119)
01-10 19:40:49.849: ERROR/AndroidRuntime(206):     at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1863)
01-10 19:40:49.849: ERROR/AndroidRuntime(206):     at android.os.Handler.dispatchMessage(Handler.java:99)
01-10 19:40:49.849: ERROR/AndroidRuntime(206):     at android.os.Looper.loop(Looper.java:123)
01-10 19:40:49.849: ERROR/AndroidRuntime(206):     at android.app.ActivityThread.main(ActivityThread.java:4363)
01-10 19:40:49.849: ERROR/AndroidRuntime(206):     at java.lang.reflect.Method.invokeNative(Native Method)
01-10 19:40:49.849: ERROR/AndroidRuntime(206):     at java.lang.reflect.Method.invoke(Method.java:521)
01-10 19:40:49.849: ERROR/AndroidRuntime(206):     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:860)
01-10 19:40:49.849: ERROR/AndroidRuntime(206):     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:618)
01-10 19:40:49.849: ERROR/AndroidRuntime(206):     at dalvik.system.NativeStart.main(Native Method)
01-10 19:40:49.849: ERROR/AndroidRuntime(206): Caused by: java.lang.IllegalStateException: get field slot from row 0 col -1 failed
01-10 19:40:49.849: ERROR/AndroidRuntime(206):     at android.database.CursorWindow.getString_native(Native Method)
01-10 19:40:49.849: ERROR/AndroidRuntime(206):     at android.database.CursorWindow.getString(CursorWindow.java:329)
01-10 19:40:49.849: ERROR/AndroidRuntime(206):     at android.database.AbstractWindowedCursor.getString(AbstractWindowedCursor.java:49)
01-10 19:40:49.849: ERROR/AndroidRuntime(206):     at it.mirko.persone.dettagli.onCreate(dettagli.java:33)
01-10 19:40:49.849: ERROR/AndroidRuntime(206):     at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1047)
01-10 19:40:49.849: ERROR/AndroidRuntime(206):     at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2459)
01-10 19:40:49.849: ERROR/AndroidRuntime(206):     ... 11 more

Questo è il logcat... Io non so leggerlo, a parte il fatto che mi dice che l'errore è in dettagli.java come io già sospettavo... :-)

Offline Nicola_D

  • Moderatore
  • Utente storico
  • *****
  • Post: 2479
  • SBAGLIATO!
  • Respect: +323
    • Github
    • Google+
    • nicoladorigatti
    • Mostra profilo
  • Dispositivo Android:
    Nexus 6p, Nexus 4, Nexus S, Nexus 7(2012)
  • Sistema operativo:
    Windows 7
Re:Listview con Database e Searchbox
« Risposta #8 il: 10 Gennaio 2011, 21:01:09 CET »
+1
get field slot from row 0 col -1 failed
vuol dire che quando fai:
personeName.setText(cursor.getString(cursor.getColumnIndex("Nome")) + " " + cursor.getString(cursor.getColumnIndex("Cognome")));
oppure
personeDettagli.setText(cursor.getString(cursor.getColumnIndex("Dettagli")));
Quale dei due è in riga 33?
il problema è che non trova una colonna che si chiama Nome,Cognome o Dettagli.

Ti dico la mia idea:
l'errore è il secondo, perchè cerchi di prendere dal cursor la stringa nella colonna Dettagli, che però non chiedi quando fai la query (chiedi solo id,nome,cognome).
Aggiungi dettagli nella select della query e secondo me poi va...
IMPORTANTE:NON RISPONDO A PROBLEMI VIA MESSAGGIO PRIVATO
LOGCAT: Non sai cos'è? -> Android Debug Bridge | Android Developers
               Dov'è in Eclipse? -> Window -> Open Prospective -> DDMS e guarda in basso!
[Obbligatorio] Logcat, questo sconosciuto! (Gruppo AndDev.it LOGTFO) - Android Developers Italia

Offline Antonio

  • Nuovo arrivato
  • *
  • Post: 7
  • Respect: 0
    • Mostra profilo
Re:Listview con Database e Searchbox
« Risposta #9 il: 10 Gennaio 2011, 21:31:22 CET »
0
L'errore era proprio quello... Se avessi un po' più di esperienza l'avrei sicuramente notato... C'è pure scritto... Prendi dal cursor la colonna dettagli... Ma se il cursor non ce l'ha, va in panico...

Grazie... Penso che non metterò più mani in questo codice... Al massimo andrò a modificare gli xml...

Per il momento "Topico Risolto"...

 :-)

Offline Ricky`

  • Amministratore
  • Utente storico
  • *****
  • Post: 3489
  • Respect: +506
    • Github
    • Google+
    • rciovati
    • Mostra profilo
Re:Listview con Database e Searchbox
« Risposta #10 il: 10 Gennaio 2011, 22:05:03 CET »
0
L'errore era proprio quello... Se avessi un po' più di esperienza l'avrei sicuramente notato... C'è pure scritto... Prendi dal cursor la colonna dettagli... Ma se il cursor non ce l'ha, va in panico...

Grazie... Penso che non metterò più mani in questo codice... Al massimo andrò a modificare gli xml...

Per il momento "Topico Risolto"...

 :-)

Se il topic è risolto è risolto per sempre. Se hai altri problemi aprine un altro perché altrimenti non si capisce più niente.  ;-)

Offline francle81

  • Nuovo arrivato
  • *
  • Post: 3
  • Respect: 0
    • Mostra profilo
Re:Listview con Database e Searchbox
« Risposta #11 il: 21 Gennaio 2011, 09:47:29 CET »
0
Potresti allegare il tuo codice ;)?

Grazie