Autore Topic: Aggiornare il contenuto di un elemento di una ListView complessa  (Letto 1037 volte)

Offline jagam

  • Nuovo arrivato
  • *
  • Post: 17
  • Respect: 0
    • Mostra profilo
0
Il mio problema è relativo ad una ListView "complessa" (un item è composto da più TextView e un ImageView) che ho associato ad un adapter personalizzato.

Al click lungo sull'item della lista creo un context menu, ma non riesco ad aggiornare il contenuto degli elementi TextView che compongono l'item.

Di seguito xml dell'item:
Codice (XML): [Seleziona]
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
   android:layout_width="match_parent"
   android:layout_height="50dp" >

    <TextView
       android:id="@+id/item_txtP"
       android:layout_width="230dp"
       android:layout_height="wrap_content"
       android:layout_above="@+id/item_txtQ"
       android:layout_alignParentTop="true"
       android:layout_toRightOf="@+id/item_icon"
       android:text="txtP"
       android:focusable="false"
       android:textAppearance="?android:attr/textAppearanceLarge" />

    <TextView
       android:id="@+id/item_txtQ"
       android:layout_width="50dp"
       android:layout_height="wrap_content"
       android:layout_alignBottom="@+id/item_icon"
       android:layout_alignLeft="@+id/item_txtP"
       android:focusable="false"
       android:text="Quota" />

    <ImageView
       android:id="@+id/item_icon"
       android:layout_width="wrap_content"
       android:layout_height="wrap_content"
       android:layout_alignParentBottom="true"
       android:layout_alignParentLeft="true"
       android:layout_alignParentTop="true"
       android:adjustViewBounds="true"
       android:maxHeight="100dp"
       android:maxWidth="100dp"
       android:focusable="false"
       android:src="@drawable/arrow_right" />

    <TextView
       android:id="@+id/item_txtRG"
       android:layout_width="wrap_content"
       android:layout_height="wrap_content"
       android:layout_alignParentBottom="true"
       android:layout_alignRight="@id/item_txtP"
       android:layout_below="@+id/item_txtP"
       android:layout_centerHorizontal="true"
       android:focusable="false"
       android:text="RG" />
               
    <TextView
       android:id="@+id/item_txtC"
       android:layout_width="wrap_content"
       android:layout_height="wrap_content"
       android:layout_alignParentBottom="true"
       android:layout_alignParentRight="true"
       android:layout_alignParentTop="true"
       android:layout_toRightOf="@+id/item_txtP"
       android:gravity="center_vertical|center_horizontal"
       android:text="NO"
       android:focusable="false"
       android:textAppearance="?android:attr/textAppearanceLarge" />
               
</RelativeLayout>

Di seguito il java file:
Codice (Java): [Seleziona]
public class ListViewDemoActivity extends Activity {
        private List<ElementoListView> myElements = new ArrayList<ElementoListView>();

        int IdElemento;
        double Vnc;
        TextView tvVnc;
        Button btnAggiungi;
        ListView list;
        ElementoListView clickedItem;
       
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

                Vnc=0;
                btnAggiungi=(Button) findViewById(R.id.addBtn);
                tvVnc=(TextView) findViewById(R.id.txtVnc);
       
        btnAggiungi.setOnClickListener(new View.OnClickListener() {
                        @Override
                        public void onClick(View v) {
                                Vnc=124.50d;
                        tvVnc.setText("Numero = " + Vnc);
                        }
        });
       
        samplePopulateList();
       
        ArrayAdapter<ElementoListView> adapter = new MyListAdapter();
                ListView list = (ListView) findViewById(R.id.listView);
                list.setAdapter(adapter);        
               
                registerForContextMenu(list);
    }
   
    @Override
    public void onCreateContextMenu(ContextMenu menu, View v,
                ContextMenuInfo menuInfo) {
        if (v.getId()==R.id.listView) {
            AdapterView.AdapterContextMenuInfo info = (AdapterView.AdapterContextMenuInfo)menuInfo;

            IdElemento=info.position;
            clickedItem = myElements.get(info.position);

            menu.setHeaderTitle(clickedItem.get1() + " Vs " + clickedItem.get2());
                String[] menuItems = getResources().getStringArray(R.array.menu_contestuale);
                for (int i = 0; i<menuItems.length; i++) {
                        menu.add(Menu.NONE, i, i, menuItems[i]);
                        }
        }
    }
   
    @Override
    public boolean onContextItemSelected(MenuItem item) {
            AdapterView.AdapterContextMenuInfo info = (AdapterView.AdapterContextMenuInfo)item.getMenuInfo();
            int menuItemIndex = item.getItemId();
            String[] menuItems = getResources().getStringArray(R.array.menu_contestuale);
            String menuItemName = menuItems[menuItemIndex];
            String listItemName = myElements.toString();

[color=green]// 1° metodo (cancello l'elemento e lo riscrivo modificato)---------------------------------------------------------------------------------------------------------------
            myElements.remove(IdElemento);  
            myElements.add(new ElementoListView("Modificato1", "Modificato2", "2", 100d, R.drawable.arrow_right, "SI"));
//----------------------------------------------------------------------------------------------------------------------------------------------------------       

// 2° metodo (cancello l'elemento e lo riscrivo modificato)---------------------------------------------------------------------------------------------------------------
            View v = list.getChildAt(menuItemIndex - list.getFirstVisiblePosition());
                    TextView text = (TextView) v.findViewById(R.id.item_txtC);
                    someText.setText("SI");
//-------------------------------------------------------------------------------------------------------------------------
[/color]
            TextView text = (TextView)findViewById(R.id.txtVnc);
            text.setText(String.format("Selected %s ", menuItemName, listItemName));

            return true;
    }

        private void samplePopulateList() {
                myElements.add(new ElementoListView("Testo1", "Testo2", "1", 1.50d, R.drawable.arrow_right, "NO"));
                myElements.add(new ElementoListView("Testo3", "Testo4", "2", 4.50d, R.drawable.arrow_right, "NO"));
        }

}

Il problema è che non riesco a modificare l'item ed aggiornare la ListView.

Qualcuno può aiutarmi???

Grazie.

Offline GabMarioPower

  • Moderatore globale
  • Utente senior
  • *****
  • Post: 606
  • Respect: +152
    • Github
    • Google+
    • gabrielemariotti
    • GabMarioPower
    • Mostra profilo
  • Play Store ID:
    GAB+MARIO+DEV
  • Sistema operativo:
    Ubuntu 14.04 , Win 10
Re:Aggiornare il contenuto di un elemento di una ListView complessa
« Risposta #1 il: 30 Agosto 2013, 08:45:31 CEST »
0
Dovresti aggiornare l'elemento dentro l'adapter, e poi lanciare il notifySetDataChanged.

Offline jagam

  • Nuovo arrivato
  • *
  • Post: 17
  • Respect: 0
    • Mostra profilo
Re:Aggiornare il contenuto di un elemento di una ListView complessa
« Risposta #2 il: 30 Agosto 2013, 14:04:06 CEST »
0
Grazie per la risposta, ma ti spiacerebbe esplicitare meglio, magari con il codice relativo?
Sai, dopo aver tanto cercato una soluzione credo di essermi bloccato sulle mie idee.
Grazie.

Inviato dal mio GT-I9300 con Tapatalk 2


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:Aggiornare il contenuto di un elemento di una ListView complessa
« Risposta #3 il: 30 Agosto 2013, 15:03:39 CEST »
0
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 GabMarioPower

  • Moderatore globale
  • Utente senior
  • *****
  • Post: 606
  • Respect: +152
    • Github
    • Google+
    • gabrielemariotti
    • GabMarioPower
    • Mostra profilo
  • Play Store ID:
    GAB+MARIO+DEV
  • Sistema operativo:
    Ubuntu 14.04 , Win 10
Re:Aggiornare il contenuto di un elemento di una ListView complessa
« Risposta #4 il: 30 Agosto 2013, 15:19:15 CEST »
0
Grazie per la risposta, ma ti spiacerebbe esplicitare meglio, magari con il codice relativo?
Sai, dopo aver tanto cercato una soluzione credo di essermi bloccato sulle mie idee.
Grazie.

Inviato dal mio GT-I9300 con Tapatalk 2

E' un pò complicato spiegare una cosa del genere in un forum.
Ci sono molte guide, tutorial a riguardo sicuramente più esaustive e precise di queste poche righe che troverai qui sotto.

In linea di massima, una listView viene popolata dall'Adapter.
Nel tuo caso è l'arrayAdapter che va a popolare (metodo getView) gli item della lista.
Non puoi andare ad aggiornare un elemento UI preso dal layout di una singola riga della listView.

Tramite il valore position puoi recuperare l'item corrispondente all'interno dell'Adapter, che nel tuo caso è un oggetto di tipo ElementoListView.
A quel punto modifichi il valore di uno oggetto, e lanci adapter.notifySetDataChanged che si preoccuperà di notificare alla lista che l'adapter ha dati modificati e di conseguenza si aggiornerà a video.


Offline jagam

  • Nuovo arrivato
  • *
  • Post: 17
  • Respect: 0
    • Mostra profilo
Re:Aggiornare il contenuto di un elemento di una ListView complessa
« Risposta #5 il: 31 Agosto 2013, 00:41:27 CEST »
0
ci sono parecchi tutorial nella sezione view e layout, tipo:
[facile] Aggiornare ListView popolata da un cursor + download e parsing JSON - Android Developers Italia

Grazie Nicola, ma avevo già cercato senza trovare qualcosa che faccia al caso mio. (Forse non ho inserito bene i criteri di ricerca).


E' un pò complicato spiegare una cosa del genere in un forum.
Ci sono molte guide, tutorial a riguardo sicuramente più esaustive e precise di queste poche righe che troverai qui sotto.

In linea di massima, una listView viene popolata dall'Adapter.
Nel tuo caso è l'arrayAdapter che va a popolare (metodo getView) gli item della lista.
Non puoi andare ad aggiornare un elemento UI preso dal layout di una singola riga della listView.

Tramite il valore position puoi recuperare l'item corrispondente all'interno dell'Adapter, che nel tuo caso è un oggetto di tipo ElementoListView.
A quel punto modifichi il valore di uno oggetto, e lanci adapter.notifySetDataChanged che si preoccuperà di notificare alla lista che l'adapter ha dati modificati e di conseguenza si aggiornerà a video.

Grazie Gabriele, forse avevo bisogno di un confronto poiché le tue parole mi hanno aperto la mente, e sono riuscito a risolvere.

Di seguito riporto le righe che mi hanno consentito di aggiornare la ListView, anche se forse in maniera un po rozza:
Codice (Java): [Seleziona]
       
// Utilizzo un oggetto di tipo ElementoListView con i "contenuti" modificati come volevo, dell'item "complesso" della ListView
ElementoListView mod_myElements = new ElementoListView(clickedItem.get1(),
           clickedItem.get2(), clickedItem.get3(),
           clickedItem.get4(), clickedItem.get5,
           String.format("%s", menuItemName, listItemName));

//Utilizzo il metodo set dell'oggetto myElements passando come parametri l'id dell'item cliccato e l'oggetto da sostituire sopra definito (ovviamente dello stesso tipo del primo).
            myElements.set(IdElemento, mod_myElements);

//Aggiorno "visivamente" la ListView
            ArrayAdapter<ElementoListView> adapter = new MyListAdapter();
            ListView list = (ListView) findViewById(R.id.listView);
            list.setAdapter(adapter);

Grazie per l'aiuto e se qualcuno ritenesse che la procedura sopra descritta possa essere in qualche modo errata da qualsiasi punto di vista, sarò ben lieto di accoglierne le riflessioni.

A presto.

Jagam