Autore Topic: AutoCompleteTextView: aggiungere valori ed evitare duplicati  (Letto 924 volte)

Offline pivot

  • Nuovo arrivato
  • *
  • Post: 49
  • Respect: +1
    • Mostra profilo
  • Dispositivo Android:
    HTC Desire
  • Sistema operativo:
    Windows
AutoCompleteTextView: aggiungere valori ed evitare duplicati
« il: 01 Settembre 2011, 15:59:56 CEST »
0
Mi sto s-cervellando sul componente in oggetto. Devo utilizzare un AutoCompleteTextView aggiungendo i valori da proporre dinamicamente.

Inizialmente pensavo di dover aggiungere i nuovi valori alla lista che si passa in fase di creazione del relativo Adapter (ArrayAdapter in questo caso), ma non funzionava. Poi ho capito che bisogna utilizzare il metodo add dell'Adapter stesso.

Ora però non riesco ad evitare i valori duplicati. Nonostante controlli il contenuto tramite i metodi getCount e getItem dell'adapter per verificare che un valore non sia già stato immesso, mi ritrovo i duplicati. In effetti ho notato che quando scorro l'elenco degli elementi non li vedo tutti.

Dove sbaglio?

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:AutoCompleteTextView: aggiungere valori ed evitare duplicati
« Risposta #1 il: 01 Settembre 2011, 20:50:08 CEST »
0
getItem cosa da,una stringa? lo sa che Stringa==Stringa non è true?

considera anche un adapter personalizzato con un TreeSet o hashSet
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 pivot

  • Nuovo arrivato
  • *
  • Post: 49
  • Respect: +1
    • Mostra profilo
  • Dispositivo Android:
    HTC Desire
  • Sistema operativo:
    Windows
Re:AutoCompleteTextView: aggiungere valori ed evitare duplicati
« Risposta #2 il: 02 Settembre 2011, 09:50:34 CEST »
0
Uso il confronto tra stringhe ovviamente

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:AutoCompleteTextView: aggiungere valori ed evitare duplicati
« Risposta #3 il: 02 Settembre 2011, 09:55:39 CEST »
0
posta un po di codice, cosi su due piedi non riesco a dirti cos'è!
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 pivot

  • Nuovo arrivato
  • *
  • Post: 49
  • Respect: +1
    • Mostra profilo
  • Dispositivo Android:
    HTC Desire
  • Sistema operativo:
    Windows
Re:AutoCompleteTextView: aggiungere valori ed evitare duplicati
« Risposta #4 il: 02 Settembre 2011, 10:54:22 CEST »
0
Ho estrapolato quanto faccio. Non ho "esternalizzato" le stringhe per praticità.

Semplice main.xml

Codice (XML): [Seleziona]
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:orientation="vertical" android:layout_width="fill_parent"
        android:layout_height="fill_parent">
        <TextView android:layout_width="fill_parent"
                android:layout_height="wrap_content" android:text="Scrivi un valore e premi Add" />
        <AutoCompleteTextView android:id="@+id/autoCompleteTextView"
                android:text="prova" android:layout_height="wrap_content"
                android:layout_width="match_parent">
                <requestFocus></requestFocus>
        </AutoCompleteTextView>
        <Button android:text="Add" android:id="@+id/buttonAdd"
                android:layout_height="wrap_content" android:layout_width="match_parent"></Button>
</LinearLayout>

Segue l'activity principale (ProvaAutoCompleteActivity):
Codice (Java): [Seleziona]
package local.ProvaAutoComplete;

import java.util.ArrayList;

import android.app.Activity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.ArrayAdapter;
import android.widget.AutoCompleteTextView;
import android.widget.Button;

public class ProvaAutoCompleteActivity extends Activity {
        private AutoCompleteTextView autoCompleteTextView;
        private ArrayAdapter<String> autoCompleteAdapter;
        private ArrayList<String> autoCompleteList = new ArrayList<String>(10);
       
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        //Preparo l'adapter
        autoCompleteAdapter = new ArrayAdapter<String>(this,
                                R.layout.autocomplete_item, autoCompleteList);
        autoCompleteAdapter.setNotifyOnChange(true);
        //imposto l'AutoCompleteTextView
        autoCompleteTextView= (AutoCompleteTextView)findViewById(R.id.autoCompleteTextView);
        autoCompleteTextView.setAdapter(autoCompleteAdapter);
       
        //Gestisco pulsante per aggiunta elementi
        Button btnAdd=(Button)findViewById(R.id.buttonAdd);
        btnAdd.setOnClickListener(new OnClickListener() {
                       
                        @Override
                        public void onClick(View v) {
                                addElement(autoCompleteTextView.getText().toString(),autoCompleteAdapter);
                        }
                });
    }
   
    private boolean isAlreadyPresent(String s, ArrayAdapter<String> adapter) {
                for (int i = 0; i < adapter.getCount(); i++)
                        if (s.equalsIgnoreCase(adapter.getItem(i)))
                                return true;
                return false;
        }
   
    private void addElement(String s, ArrayAdapter<String> adapter) {
        boolean added=false;
                // verifico se già esistente prima di aggiungere e che non sia stringa vuota
                if (s.trim().length()>0 && !isAlreadyPresent(s, adapter)) {
                        adapter.add(s);
                        added=true;
                }
                //Un po' di DEBUG
                Log.d("ProvaAutoCompleteActivity","Stringa '"+s+"' "+(added?"":"NON")+" aggiunta");
                Log.d("ProvaAutoCompleteActivity","  -->  Adapter Elements: "+getList(adapter));
                Log.d("ProvaAutoCompleteActivity","  -->  List Elements: "+getList(autoCompleteList));
        }

        //Per DEBUG
        private String getList(ArrayAdapter<String> adapter) {
                String result="[ ";
                int size=adapter.getCount();
                for (int i = 0; i < size; i++) {
                        result += adapter.getItem(i);
                        if (i<size-1)
                                result += "; ";
                }
                result += " ]";
                return result;
        }

        //Per DEBUG
        private String getList(ArrayList<String> list) {
                String result="[ ";
                int size=list.size();
                for (int i = 0; i < size; i++) {
                        result += list.get(i);
                        if (i<size-1)
                                result += "; ";
                }
                result += " ]";
                return result;
        }
}

Ora se si lancia l'applicazione procedere in questo modo:

1. Lasciare il testo proposto ("prova") e premere "Add"
2. modificare il testo, io ho scritto "prova1" e premere "Add"
3. senza modificare il testo ripremere "Add", mi aspetterei che non venisse riaggiunto il testo già presente. Se invece scrivete "pr", troverete i doppioni.

Esito del log:


Stringa 'prova'  aggiunta
  -->  Adapter Elements: [ prova ]
  -->  List Elements: [ prova ]
Stringa 'prova1'  aggiunta
  -->  Adapter Elements: [  ]
  -->  List Elements: [ prova ]
Stringa 'prova1'  aggiunta
  -->  Adapter Elements: [  ]
  -->  List Elements: [ prova ]


Si evince che i filtri applicati per le proposte rimangono applicati e quindi non vedo l'intero elenco. La lista che passo inizialmente non sembra si aggiorni.

Dove sbaglio?

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:AutoCompleteTextView: aggiungere valori ed evitare duplicati
« Risposta #5 il: 02 Settembre 2011, 11:10:01 CEST »
0
io non farei come hai fatto ma cosi:
chiamiamo le cose cosi:
Adapter (arrayAdapter)
Lista (lista che inizializzi nella classe  e usi per l'adapter)
Item (stringa semplice)

l'inizio va bene
poi quando scrivi il testo e premi add fai:
Lista.contains(newItem.trim);
if true TOAST DI STRINGA PRESENTE
else lista.add(newItem.trim)
adapter.notifyDataSetChanged

e dovresti essere a posto
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 pivot

  • Nuovo arrivato
  • *
  • Post: 49
  • Respect: +1
    • Mostra profilo
  • Dispositivo Android:
    HTC Desire
  • Sistema operativo:
    Windows
Re:AutoCompleteTextView: aggiungere valori ed evitare duplicati
« Risposta #6 il: 02 Settembre 2011, 11:26:12 CEST »
0
E io ti darei anche ragione, infatti ero partito con la tua stessa idea. Solo che il primo elemento che aggiungi lo vedi nella lista dell'autocompletamento, tutti gli altri no.

Prova:

Codice (Java): [Seleziona]
package local.ProvaAutoComplete;

import java.util.ArrayList;

import android.app.Activity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.ArrayAdapter;
import android.widget.AutoCompleteTextView;
import android.widget.Button;

public class ProvaAutoCompleteActivity extends Activity {
        private AutoCompleteTextView autoCompleteTextView;
        private ArrayAdapter<String> autoCompleteAdapter;
        private ArrayList<String> autoCompleteList = new ArrayList<String>(10);
       
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        //Preparo l'adapter
        autoCompleteAdapter = new ArrayAdapter<String>(this,
                                R.layout.autocomplete_item, autoCompleteList);
        autoCompleteAdapter.setNotifyOnChange(true);
        //imposto l'AutoCompleteTextView
        autoCompleteTextView= (AutoCompleteTextView)findViewById(R.id.autoCompleteTextView);
        autoCompleteTextView.setAdapter(autoCompleteAdapter);
       
        //Gestisco pulsante per aggiunta elementi
        Button btnAdd=(Button)findViewById(R.id.buttonAdd);
        btnAdd.setOnClickListener(new OnClickListener() {
                       
                        @Override
                        public void onClick(View v) {
                                //addElement(autoCompleteTextView.getText().toString(),autoCompleteAdapter);
                                addElement(autoCompleteTextView.getText().toString(),autoCompleteList);
                        }
                });
    }
   
    private boolean isAlreadyPresent(String s, ArrayAdapter<String> adapter) {
                for (int i = 0; i < adapter.getCount(); i++)
                        if (s.equalsIgnoreCase(adapter.getItem(i)))
                                return true;
                return false;
        }
   
    private void addElement(String s, ArrayList<String> list) {
        boolean added=false;
                // verifico se già esistente prima di aggiungere e che non sia stringa vuota
                if (s.trim().length()>0 && !list.contains(s.trim())) {
                        list.add(s.trim());
                        autoCompleteAdapter.notifyDataSetChanged();
                        added=true;
                }
                Log.d("ProvaAutoCompleteActivity","Stringa '"+s+"' "+(added?"":"NON")+" aggiunta");
                Log.d("ProvaAutoCompleteActivity","  -->  Adapter Elements: "+getList(autoCompleteAdapter));
                Log.d("ProvaAutoCompleteActivity","  -->  List Elements: "+getList(autoCompleteList));
        }
   
    private void addElement(String s, ArrayAdapter<String> adapter) {
        boolean added=false;
                // verifico se già esistente prima di aggiungere e che non sia stringa vuota
                if (s.trim().length()>0 && !isAlreadyPresent(s.trim(), adapter)) {
                        adapter.add(s.trim());
                        added=true;
                }
                Log.d("ProvaAutoCompleteActivity","Stringa '"+s+"' "+(added?"":"NON")+" aggiunta");
                Log.d("ProvaAutoCompleteActivity","  -->  Adapter Elements: "+getList(adapter));
                Log.d("ProvaAutoCompleteActivity","  -->  List Elements: "+getList(autoCompleteList));
        }

        private String getList(ArrayAdapter<String> adapter) {
                String result="[ ";
                int size=adapter.getCount();
                for (int i = 0; i < size; i++) {
                        result += adapter.getItem(i);
                        if (i<size-1)
                                result += "; ";
                }
                result += " ]";
                return result;
        }
       
        private String getList(ArrayList<String> list) {
                String result="[ ";
                int size=list.size();
                for (int i = 0; i < size; i++) {
                        result += list.get(i);
                        if (i<size-1)
                                result += "; ";
                }
                result += " ]";
                return result;
        }
}

Offline pivot

  • Nuovo arrivato
  • *
  • Post: 49
  • Respect: +1
    • Mostra profilo
  • Dispositivo Android:
    HTC Desire
  • Sistema operativo:
    Windows
Re:AutoCompleteTextView: aggiungere valori ed evitare duplicati
« Risposta #7 il: 04 Settembre 2011, 19:16:28 CEST »
0
Non ne vengo fuori, e mi pare impossibile che non trovo da nessuna parte qualcuno con lo stesso problema  :'(

Non vorrei riassegnare l'adapter ad ogni aggiunta di un elemento. Ci deve essere una soluzione più elegante.