JavascriptProva

Visualizzazione post con etichetta arraylist. Mostra tutti i post
Visualizzazione post con etichetta arraylist. Mostra tutti i post

domenica 10 gennaio 2016

AutoCompleteTextView: evento del click sul suggerimento.


Discriminare se si sia introdotta una categoria ex novo o se si tratti di una categoria già preesistente.
La categoria viene selezionata attraverso una AutoCompleteTextView, per cui bisogna trovare il modo di distinguere le due evenienze di "nuova categoria" o di "categoria già esistente" in questo controllo.

Forse ho trovato qualcosa...

Bene. Costruiamo un programma con una AutoComplete che esegua un certo programma solo se viene inserito nuovo testo rispetto a uno suggerito.

Ho creato un AutoCompleteTextView:
public class MainActivity extends Activity {
 
 AutoCompleteTextView autoComplete;
 
 @Override
 protected void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  
  setContentView(R.layout.activity_main);
  
  autoComplete = (AutoCompleteTextView)findViewById(R.id.autoCompleteTextView1);
  
  
 }
Ora dovrei usare un adapter per connetterla a una lista.
Prima ancora mi serve una lista: procedo a creare un'ArrayList:
  
  ArrayList<String> lista=new ArrayList<String>();
  
  String[] matrice={"lunedi","martedi","mercoledi","giovedi","venerdi","sabato","domenica"};
  
  lista.addAll(Arrays.asList(matrice)); 
E ho trovato anche il modo di riempire un'ArrayList senza stare lì a dare tremila righe di codice: dichiarare e istanziare un array e poi aggiungere il contenuto di quest'array tutto in un colpo.

Bene, ora che ho creato la lista devo connetterla mediante un adapter alla AutoCompleteTextView.
Come fare?

Estendiamo un ArrayAdapter... anzi no, non estendiamo un bel niente: mi serve un ArrayAdapter così com'è...
public class MainActivity extends Activity {
 
 AutoCompleteTextView autoComplete;
 
 
 
 @Override
 protected void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  
  setContentView(R.layout.activity_main);
  
  autoComplete = (AutoCompleteTextView)findViewById(R.id.autoCompleteTextView1);
  
  ArrayList lista=new ArrayList();
  
  String[] matrice={"lunedi","martedi","mercoledi","giovedi","venerdi","sabato","domenica"};
  
  lista.addAll(Arrays.asList(matrice));
  
  Log.d("LISTA",lista.get(0));
  ArrayAdapter myArrAdapter = new ArrayAdapter(this,android.R.layout.simple_list_item_1,lista);
  
  autoComplete.setAdapter(myArrAdapter);
  
  
 }
La sintassi dell'ArrayAdapter è molto più semplice di quella del BaseAdapter che ho esteso finora: l'ho fatto sempre per la mia mania di voler andare nel cuore delle cose, ma è più comodo prendersi un ArrayAdapter già bello e costruito.

Ecco: come view da estendere si usa espressamente android.R.layout.simple_list_item_1, e il gioco è fatto.

Nella mia applicazione, ho una AutoCompleteTextView che dà il valore al campo categoria del database.
Ora a ogni categoria va abbinata un'immagine, che avrà il suo path, il quale andrà memorizzato in un altro campo del database. Ma non sarà più economico creare un'altra tabella con un abbinamento categorie-immagini anziché creare un altro campo nella tabella contenente il path dell'immagine?
Se la categoria è sconosciuta, scegliere l'immagine e aggiungere alla tabella delle categorie un nuovo record categoria con il path; se la categoria è conosciuta evitare il codice che fa tutto questo... Poi però all'atto della selezione per popolare la ListView dell'activity principale si deve andare sulla nuova tabella categorie-path, così si può evitare il distinct. E nel momento in cui viene operata la scelta delle categorie si fa una query basata su un where... Sì, mi sa che devo rivedere da capo quell'applicazione, smontare di sana pianta i database e rifarli con un criterio più razionale!
Ora però mi devo occupare della mia AutoCompleteTextView...

Con il codice di cui sopra, la AutoComplete funziona!
Ora provo giusto l'evento click sul suggerimento...

public class MainActivity extends Activity {
 
 AutoCompleteTextView autoComplete;
 
 
 
 @Override
 protected void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  
  setContentView(R.layout.activity_main);
  
  autoComplete = (AutoCompleteTextView)findViewById(R.id.autoCompleteTextView1);
  
  ArrayList lista=new ArrayList();
  
  String[] matrice={"lunedi","martedi","mercoledi","giovedi","venerdi","sabato","domenica"};
  
  lista.addAll(Arrays.asList(matrice));
  
  Log.d("LISTA",lista.get(0));
  ArrayAdapter myArrAdapter = new ArrayAdapter(this,android.R.layout.simple_list_item_1,lista);
  
  autoComplete.setAdapter(myArrAdapter);
  
  
  autoComplete.setOnItemClickListener(new AdapterView.OnItemClickListener() {

   @Override
   public void onItemClick(AdapterView parent, View view,
     int position, long id) {
    Log.d("AUTOCOMPLETE","ITEMCLICK");
    
   }
   
  });
Funziona! Ottengo in LogCat le stringhe "AUTOCOMPLETE" "ITEMCLICK" solo quando clicco sul suggerimento!
Questo mi può permettere di aggiungere alla tabella categorie del mio ipotetico nuovo database solo nel caso in cui questo suggerimento non venga cliccato.
Ci vorrà anche un elemento di maggiore sicurezza, ossia non inserire nel database una nuova categoria dal nome uguale al precedente: bisogna creare campi con valore unico...

sabato 7 settembre 2013

Copiare un ArrayList in una matrice (array) e riempire un ArrayList con linee di un file di testo, da trasferire in un array.

Public Class Form1
    Dim insieme As ArrayList
    Dim matrice As String()
    Private Sub Form1_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles MyBase.Load
        insieme = New ArrayList
        insieme.Add("gongolo")
        insieme.Add("mammolo")
        insieme.Add("pisolo")
        ReDim matrice(insieme.Count)
        insieme.CopyTo(matrice)
        Debug.Print(matrice(0) & " " & matrice(1) & " " & matrice(2))
    End Sub
End Class
gongolo mammolo pisolo
Bene. Con questo codice ho trascritto il valore di un ArrayList in un array di stringhe.

Adesso il codice che anzichè immettere manualmente gli elementi in un ArrayList li prende da un file.
Creo il file settenani.txt
gongolo
pisolo
mammolo
eolo
dotto
brontolo
cucciolo
E adesso lo "prendo" con l'istruzione FileOpen, trascrivendo ogni linea del file in una variabile stringa e apponendolo all'ArrayList, quindi ridimensiono un array di stringhe alla stessa lunghezza dell'ArrayList e vi trascrivo i valori di questo:
Public Class Form1
    Dim insieme As New ArrayList
    Dim matrice As String()
    Private Sub Form1_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles MyBase.Load
        Dim str As String = String.Empty
        Dim n As Integer = 1
        FileOpen(1, "C:\Users\Antonello\Desktop\settenani.txt", OpenMode.Input)
        Do Until EOF(1)
            str = LineInput(1)
            insieme.Add(str)
        Loop
        ReDim matrice(insieme.Count)
        insieme.CopyTo(matrice)
        For Each elemento In matrice
            Debug.Print(elemento)
        Next
    End Sub
End Class
Ecco il risultato nella finestra di debug, dove il programma dice di stampare gli elementi della matrice di stringhe:
gongolo
pisolo
mammolo
eolo
dotto
brontolo
cucciolo
Dunque l'aver preso le linee del file di testo, l'averle messe in un ArrayList e quindi trascritte in un array di stringhe funziona.
Si potrebbe chiedersi perchè non mettere direttamente tutto in un array di stringhe: il problema è che a ogni mutamento di dimensioni di un array questo viene ritrascritto di sana pianta in un'altra locazione della memoria, e l'operazione è poco efficiente.

venerdì 6 settembre 2013

Eliminare un elemento di un arraylist se individuato. Metodo Clone...

Costruiamo un codice in cui da un array viene eliminata una voce che vi sia contenuta, se digitata in una textbox.
Public Class Form1
    Dim elenco As New ArrayList
    Dim copia As ArrayList

    Private Sub Form1_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles MyBase.Load
        With elenco
            .Add("gongolo")
            .Add("eolo")
            .Add("dotto")
            .Add("mammolo")
            .Add("pisolo")
            .Add("brontolo")
            .Add("cucciolo")
        End With
        copia = DirectCast(elenco.Clone, ArrayList)
        elenca(ListBox1, elenco)
        elenca(ListBox2, copia)
    End Sub
    Sub elenca(ByRef lista As ListBox, ByVal matrice As ArrayList)
        For Each elemento In matrice
            lista.Items.Add(elemento)
        Next
    End Sub

    Private Sub Button1_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles Button1.Click
        If copia.Contains(TextBox1.Text) Then
            copia.Remove(TextBox1.Text)
            ListBox1.Items.Clear()
            ListBox2.Items.Clear()
            elenca(ListBox1, elenco)
            elenca(ListBox2, copia)
        End If

    End Sub
End Class
Ecco. Il metodo Clone() non l'ho capito in pieno. Dovrebbe fare una "copia superficiale" di un array, laddove per copia "superficiale" si intenderebbe solo i riferimenti a eventuali oggetti piuttosto che una copia degli oggetti stessi... Ma se gli elementi non sono oggetti, non ci dovrebbe essere nessuna differenza... Non so. Probabilmente capirò in seguito...