Autore Topic: Refresh ListView CursorAdapter  (Letto 648 volte)

Offline Eskilop

  • Nuovo arrivato
  • *
  • Post: 12
  • Respect: 0
    • Mostra profilo
  • Dispositivo Android:
    Google Nexus 5, samsung galaxy next turbo
  • Play Store ID:
    Eskilop
  • Sistema operativo:
    Windows 8, Ubuntu 14.10
Refresh ListView CursorAdapter
« il: 15 Dicembre 2014, 18:06:13 CET »
0
Salve, si, sono tornato, con un altro problema, sto creando un app che deve leggere dei dati da un database SQLite, è tutto a posto, faccio tutto senza problemi, se non fosse che appena l'utente aggiunge o elimina un elemento la relativa ListView rimane statica, non si aggiorna, non fa nulla, se l'activity viene chiusa e riaperta allora la lista viene correttamente aggiornata, ho provato già il metodo seguente:
Codice (Java): [Seleziona]
cursoradapter.notifyDataSetChanged();mettendolo dove mi sembrava piu' adatto, dove sbaglio e come posso fare il refresh della listview? Vi allego il codice dell'activity:
Codice (Java): [Seleziona]
public class InventActivity extends ActionBarActivity {

    private DbManager dbm = null;
    private CursorAdapter cadapter;
    private ListView lv = null;

    private View.OnClickListener onclicklistener = new View.OnClickListener() {
        @Override
        public void onClick(View v)
        {
            int position=lv.getPositionForView(v);
            long id=cadapter.getItemId(position);
            if (dbm.deletei(id))
                cadapter.changeCursor(dbm.queryi());
        }
    };

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_invent);

        final EditText invobj = (EditText)findViewById(R.id.object);
        Button addi = (Button)findViewById(R.id.addobj);
        dbm = new DbManager(getApplicationContext());
        lv = (ListView)findViewById(R.id.listViewi);
        final Cursor cur = dbm.queryi();

        cadapter = new CursorAdapter(getApplicationContext(), cur, 0) {
            @Override
            public View newView(Context ctx, Cursor arg1, ViewGroup arg2)
            {
                View v=getLayoutInflater().inflate(R.layout.tile, null);
                return v;
            }

            @Override
            public void bindView(View v, Context arg1, Cursor crs)
            {
                String inv=crs.getString(crs.getColumnIndex(Database.DatabaseStrings.FIELD_INVENTORY));
                TextView txt=(TextView) v.findViewById(R.id.txt_subject);
                txt.setText(inv);
                ImageView del=(ImageView) v.findViewById(R.id.btn_delete);
                del.setOnClickListener(onclicklistener);
            }

            @Override
            public long getItemId(int position)
            {
                Cursor curs=cadapter.getCursor();
                curs.moveToPosition(position);
                return curs.getLong(curs.getColumnIndex(Database.DatabaseStrings.FIELD_ID));
            }
        };

        lv.setAdapter(cadapter);


        addi.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if (invobj.length()!=0){
                    String obj = invobj.getText().toString();
                    dbm.savei(obj); //Viene salvata la stringa inserita nel database
                    invobj.setText(""); //L'EditText viene pulito
                }

            }
        });

    }

}
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:Refresh ListView CursorAdapter
« Risposta #1 il: 15 Dicembre 2014, 18:37:46 CET »
+1
Se ho ben capito la problematica, il tutto dovrebbe essere dovuto al fatto che notifyDatasetChanged() agisce sull'adapter, dicendogli che il dataset è stato cambiato. Ma il tuo adapter ha come dataset il Cursor, che non è cambiato.

In teoria potrebbe bastare chiamare requery() sul Cursor e questa dovrebbe ricaricare il Cursor stesso con i dati cambiati, più chiamare automaticamente la notifyDatasetChanged()
NON rispondo a domande nei messaggi privati
Bradipao @ Play Store

Offline Eskilop

  • Nuovo arrivato
  • *
  • Post: 12
  • Respect: 0
    • Mostra profilo
  • Dispositivo Android:
    Google Nexus 5, samsung galaxy next turbo
  • Play Store ID:
    Eskilop
  • Sistema operativo:
    Windows 8, Ubuntu 14.10
Re:Refresh ListView CursorAdapter
« Risposta #2 il: 15 Dicembre 2014, 18:42:02 CET »
0
Se ho ben capito la problematica, il tutto dovrebbe essere dovuto al fatto che notifyDatasetChanged() agisce sull'adapter, dicendogli che il dataset è stato cambiato. Ma il tuo adapter ha come dataset il Cursor, che non è cambiato.

In teoria potrebbe bastare chiamare requery() sul Cursor e questa dovrebbe ricaricare il Cursor stesso con i dati cambiati, più chiamare automaticamente la notifyDatasetChanged()

che io sappia il metodo requery() è stato deprecato, e poi, dove dovrei posizionarlo con esattezza?

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:Refresh ListView CursorAdapter
« Risposta #3 il: 15 Dicembre 2014, 20:26:18 CET »
0
Il concetto è che appena dopo aver cambiato il database, devi aggiornare il cursor. Se requery è deprecato, puoi anche creare un nuovo cursor e assegnare quelli all'adapter.

Quindi puoi metterlo subito dopo il punto in cui aggiungi il dato al database.
NON rispondo a domande nei messaggi privati
Bradipao @ Play Store

Offline Eskilop

  • Nuovo arrivato
  • *
  • Post: 12
  • Respect: 0
    • Mostra profilo
  • Dispositivo Android:
    Google Nexus 5, samsung galaxy next turbo
  • Play Store ID:
    Eskilop
  • Sistema operativo:
    Windows 8, Ubuntu 14.10
Re:Refresh ListView CursorAdapter
« Risposta #4 il: 16 Dicembre 2014, 00:44:12 CET »
0
Il concetto è che appena dopo aver cambiato il database, devi aggiornare il cursor. Se requery è deprecato, puoi anche creare un nuovo cursor e assegnare quelli all'adapter.

Quindi puoi metterlo subito dopo il punto in cui aggiungi il dato al database.

Grazie Bradipao, stavo ricercando da giorni come fixare, sei un grande, ho risolto, grazie mille  ;-)

Offline Cleon I

  • Nuovo arrivato
  • *
  • Post: 49
  • Sono l'imperatore della galassia
  • Respect: +2
    • Google+
    • Mostra profilo
  • Dispositivo Android:
    LG L70, Nexus 7 2013
  • Sistema operativo:
    LinuxMint Cinnamon 17.1
Re:Refresh ListView CursorAdapter
« Risposta #5 il: 19 Dicembre 2014, 10:59:52 CET »
0
Grazie Bradipao, stavo ricercando da giorni come fixare, sei un grande, ho risolto, grazie mille  ;-)

Come potrei applicare questa soluzione qui: Ricaricare SimpleCursorAdpter - Android Developers Italia

Ho un'app con navigation drawer e l'aggiunta dei dati viene fatta da un'activity richiamata tramite la pressione del + sull'action bar (gestito nella classe principale) il db e il cursor vengono gestiti da una classe innestata (quella che gestisce il fragment). Come faccio al rientro dall'activity di aggiunta (che chiudo con finish appena fatto il tutto) a far fare quello che descrivete qui? Io pensavo di mettere le istruzioni dove gestisco il tasto + dell'actionbar (in onOptionsItemSelected della classe principale per intendersi)

Post unito: [time]Dicembre 19, 2014, 15:15:36[/time]
Ho risolto in maniera notevolmente differente

Pensandoci bene a me interessa che alla morte dell'activity di inserimento (e di quella di cancellazione che ho apppena creato) li cursoradapter sia ricaricato.
Ho quindi deciso di inserire un onResume nell'activity principale che riseleziona la voce di menu nel drawer (cosa che fondamenntalmente ero costretto a fare io a mano). Ecco un estratto di codice:

Codice (Java): [Seleziona]
    @Override
    protected void onResume()
    {
        super.onResume();
        if (mMenuTitles[1].equals((String) mTitle))
        {
                selectItem(1);
        }
        if (mMenuTitles[2].equals((String) mTitle))
        {
                selectItem(2);
        }
        if (mMenuTitles[3].equals((String) mTitle))
        {
                selectItem(3);
        }
       
    }
...............
..............
        private void selectItem(int position)
        {
                Fragment fragment = new PrincipalFragment();
                Bundle args = new Bundle();
                args.putInt(PrincipalFragment.ARG_AN_NUM,position);
                fragment.setArguments(args);
                FragmentManager fm = getFragmentManager();
                fm.beginTransaction().replace(R.id.content_frame,fragment).commit();
                mDrawerList.setItemChecked(position, true);
                setTitle(mMenuTitles[position]);
                mDrawerLayout.closeDrawer(mDrawerList);
        }

It works :-)

mMenuTitles è un array che contiene i titoli di tutte le voci del menu
mTitle contiene il titolo della voce di menù in uso
« Ultima modifica: 19 Dicembre 2014, 15:17:11 CET da Cleon I »