2011-12-03 15 views
6

Ho un BaseAdapter personalizzato e un pulsante Aggiungi nell'attività principale. Il pulsante apre una finestra di dialogo con una casella di testo e puoi aggiungere nuovi elementi all'elenco in questo modo. Il problema è che la lista non è aggiornata. Nella funzione onActivityResult() stampo il numero di elementi nell'elenco e ogni volta che clicco OK nella finestra di dialogo il numero aumenta, quindi so che è solo il refresh che non funziona. La mia BaseAdapter e la mia attività:Android: ListView non si aggiorna su notifyDataSetChanged();

class ListaOrase extends BaseAdapter{ 
    private Activity context; 
    ArrayList<String> orase; 

    public ListaOrase(Activity context){ 
     this.context=context; 
     orase=new ArrayList<String>(); 
    } 
    public void add(String string){ 
     orase.add(string); 
     this.notifyDataSetChanged(); 
    } 

    public View getView (int position, View convertView, ViewGroup list) { 
     View element; 
     if (convertView == null) 
     { 
     LayoutInflater inflater = context.getLayoutInflater(); 
     element = inflater.inflate(R.layout.lista, null); 
     } 
     else element = convertView; 
     TextView elementLista=(TextView)element.findViewById(R.id.elementLista);  
     elementLista.setText(orase.get(position)); 
     return element; 
    } 

} 

public class WeatherAppActivity extends ListActivity { 

    Button buton; 
    ListaOrase lista; 

    @Override 
    public void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.main); 
     lista=new ListaOrase(this); 
     buton=(Button)findViewById(R.id.buton); 


     lista.add("Bucuresti"); 
     lista.add("Sibiu"); 
     setListAdapter(lista); 

    } 

    public void add(View view){ 
     Intent intent=new Intent(); 
     intent.setClass(this, Adauga.class); 
     startActivityForResult(intent, 0); 
    } 

    public void onActivityResult (int requestCode, int responseCode, Intent data){ 
     System.out.println("Apelata"); 
     if(responseCode==1){ 
      lista.add(data.getStringExtra("oras")); // e chiar getText() 
      System.out.println(lista.getCount()); 
      lista.notifyDataSetChanged(); 
     } 
    } 
} 

Come potete vedere, sto cercando di aggiornare (notifyDataSetChanged();) sia quando si aggiunge un nuovo elemento (nella classe che estende BaseAdapter) e nel metodo onActivityResult, dopo la la finestra di dialogo passa il nuovo elemento all'attività principale. Ripeto, l'elemento viene aggiunto alla lista perché il conteggio aumenta, semplicemente non si aggiorna.

Grazie per le vostre risposte!

+0

Perché non si chiama setListAdapter (lista); in OnActivityResult – Abhi

+0

Fa il lavoro, ma gli articoli sono nulli. LogCat dice che l'elenco richiede una stringa ma ottiene una SpannableString. Cos'è e come posso liberarmene? Viene ottenuto dalla finestra di dialogo tramite un Intento. – FloIancu

+0

Ho aggiunto del codice alla mia risposta, ho cambiato il codice correggendo alcune cose e semplificando l'uso di un adattatore di array, ci sono un paio di piccoli cambiamenti molto importanti da seguire, spero che ti aiuteranno, fammi sapere! – gwa

risposta

7

È normale che non si aggiorni, si aggiunge un elemento a "lista" ma l'adattatore mantiene la propria copia di tale elenco, così o si imposta nuovamente l'elenco nell'adattatore e quindi si chiama notifyDataChanged o si aggiungi il nuovo elemento all'adattatore.

In ogni caso, vedo un paio di cose strane, io posso semplificare tutto usando un adattatore di array, non è necessario implementare add, ecc. Ho scritto qualche codice simplyfing vostro:

public class WeatherAppActivity extends ListActivity { 

Button buton; 
ItemsAdapter lista; 

@Override 
public void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.main); 

    List<String> initialList = new ArrayList<String>(); 
    initialList.add("Bucuresti"); 
    initialList.add("Sibiu"); 

    lista=new ItemsAdapter(this, initialList); 
    buton=(Button)findViewById(R.id.button1); 
    buton.setOnClickListener(new OnClickListener() { 
     @Override 
     public void onClick(View v) { 
      lista.add(""+System.currentTimeMillis()); // e chiar getText() 
      lista.notifyDataSetChanged(); 

     } 
    }); 

    setListAdapter(lista); 

} 

class ItemsAdapter extends ArrayAdapter<String> { 

    public ItemsAdapter(Context context, List<String> list) { 
     super(context, R.layout.lista, list); 
    } 

    @Override 
    public View getView(final int position, View row, final ViewGroup parent) { 
     final String item = getItem(position); 

     ItemWrapper wrapper = null; 
     if (row == null) { 
      row = getLayoutInflater().inflate(R.layout.lista, parent, false); 
      wrapper = new ItemWrapper(row); 

      row.setTag(wrapper); 
     } else { 
      wrapper = (ItemWrapper) row.getTag(); 
     } 
     wrapper.refreshData(item); 

     return row; 
    } 

    class ItemWrapper { 

     TextView text; 

     public ItemWrapper(View row) { 
      text = (TextView) row.findViewById(R.id.elementLista); 
     } 

     public void refreshData(String item) { 
      text.setText(item); 
     } 

    } 
    }  

} 

Questi sono i XML che ho usato:

main.xml

<?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="match_parent" > 

<Button 
    android:id="@+id/button1" 
    android:layout_width="wrap_content" 
    android:layout_height="wrap_content" 
    android:layout_alignParentBottom="true" 
    android:layout_centerHorizontal="true" 
    android:layout_marginBottom="63dp" 
    android:text="Button" /> 

<ListView 
    android:id="@id/android:list" 
    android:layout_width="match_parent" 
    android:layout_height="wrap_content" 
    android:layout_alignParentTop="true" 
    android:layout_centerHorizontal="true" > 
</ListView> 

</RelativeLayout> 

lista.xml

<?xml version="1.0" encoding="utf-8"?> 
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 
android:layout_width="match_parent" 
android:layout_height="match_parent" 
android:orientation="vertical" > 

<TextView 
    android:id="@+id/elementLista" 
    android:layout_width="wrap_content" 
    android:layout_height="wrap_content" 
    android:text="Medium Text" 
    android:textAppearance="?android:attr/textAppearanceMedium" /> 

</LinearLayout> 

Questo è il versione dell'adattatore utilizzando una baseadapter:

class ItemsBaseAdapter extends BaseAdapter { 

private List<String> items; 
private Context mContext; 

public ItemsBaseAdapter(Context context, List<String> list) { 
    items = list; 
    mContext = context; 
} 

public void addItem(String str) { 
    items.add(str); 
} 

@Override 
public View getView(final int position, View row, final ViewGroup parent) { 
    final String item = (String) getItem(position); 

    ItemWrapper wrapper = null; 
    if (row == null) { 
     row = getLayoutInflater().inflate(R.layout.lista, parent, false); 
     wrapper = new ItemWrapper(row); 

     row.setTag(wrapper); 
    } else { 
     wrapper = (ItemWrapper) row.getTag(); 
    } 
    wrapper.refreshData(item); 

    return row; 
} 

class ItemWrapper { 

    TextView text; 

    public ItemWrapper(View row) { 
     text = (TextView) row.findViewById(R.id.elementLista); 
    } 

    public void refreshData(String item) { 
     text.setText(item); 
    } 

} 

@Override 
public int getCount() { 
    return items.size(); 
} 

@Override 
public Object getItem(int position) { 
    return items.get(position); 
} 

@Override 
public long getItemId(int position) { 
    // TODO Auto-generated method stub 
    return 0; 
} 
} 

E questa è la versione della voce di elenco wich anche includono un'imageview a sinistra:

<?xml version="1.0" encoding="utf-8"?> 
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 
android:layout_width="match_parent" 
android:layout_height="match_parent" 
android:orientation="horizontal" > 

<ImageView 
    android:layout_height="wrap_content" 
    android:src="@android:drawable/btn_star_big_on" 
    android:scaleType="fitCenter" 
    android:layout_width="wrap_content" 
    /> 

<TextView 
    android:id="@+id/elementLista" 
    android:layout_width="wrap_content" 
    android:layout_height="wrap_content" 
    android:text="Medium Text" 
    android:textAppearance="?android:attr/textAppearanceMedium" 
    /> 

</LinearLayout>  
+0

Abhi ha aiutato (vedi commento sopra) ma sembra che abbia un problema con SpannableString (vedi risposta). Grazie per aver risposto! – FloIancu

+0

Sfortunatamente il compito richiede l'uso di un BaseAdapter. Inoltre, ho in programma di aggiungere un'icona a sinistra di ciascun elemento, che non può essere eseguita con un ArrayAdapter. Allora, cos'è quello SpannableString? – FloIancu

+0

È possibile creare l'elemento della lista in qualsiasi modo si desideri indipendentemente dal tipo di adattatore che si sta utilizzando. Ho modificato la mia risposta aggiungendo una versione di baseadapter e una voce di elenco che include anche un'icona a sinistra ... – gwa

Problemi correlati