2012-10-10 15 views
6

Questo è un seguito alla mia domanda precedente: Android: Autocomplete TextView Similar To The Facebook App.MultiAutoCompleteTextView con adattatore personalizzato visualizza stringa incomprensibile

Sfondo:

La mia esigenza nella questione (link postato qui sopra) è stato quello di avere un AutoCompleteTextView simile a quello utilizzato in app Facebook e molti altri. La soluzione era usare una linea multipla MultiAutoCompleteTextView L'idea era di consentire agli utenti di digitare direttamente i loro nomi di amici durante la creazione di un aggiornamento dello stato. La soluzione nella risposta funziona bene da un punto di vista standalone. Tuttavia, quando ho iniziato a integrare la soluzione nel mio codice esistente, funziona ancora con il corretto elenco a discesa e tutto. Vedo l'elenco filtrato dei miei amici grazie a una soluzione da qui: https://stackoverflow.com/a/12363961/1350013. Io uso un custom ListView con un BaseAdapter invece del GridView dalla soluzione.

Il problema:

Il mio codice fa uso di una BaseAdapter che implementa Filterable. Come accennato in precedenza, funziona bene.

Quando seleziono un amico dall'elenco filtrato, è dove si trova il problema. Il MultiAutoCompleteTextView, dopo la selezione, visualizza questo: @[email protected] invece del nome dell'amico. Cosa dovrei cambiare per mostrare il nome al posto del testo confuso? Se è utile, la classe I esegue questo in extend a SherlockActivity e non a SherlockListActivity.

Ora non sono sicuro del codice pertinente per scoprire dove potrebbe trovarsi il problema, quindi invierò il maggior numero possibile di codice pertinente. Sono un noob, quindi per favore sii facile e chiedi qualsiasi codice aggiuntivo. Mi accontenterò prontamente. Allo stesso modo, se qualcosa qui non è necessario è ingombrare il post, lo rimuoverò.

blocchi di codice

il tokenizzatore dalla soluzione da mia precedente domanda. Collegato in alto (Nel metodo onCreate())

editStatusUpdate = (MultiAutoCompleteTextView) findViewById(R.id.editStatusUpdate); 
editStatusUpdate.addTextChangedListener(filterTextWatcher); 

editStatusUpdate.setTokenizer(new Tokenizer() { 

    @Override 
    public CharSequence terminateToken(CharSequence text) { 

     int i = text.length(); 

     while (i > 0 && text.charAt(i - 1) == ' ') { 
      i--; 
     } 

     if (i > 0 && text.charAt(i - 1) == ' ') { 
      return text; 
     } else { 
      if (text instanceof Spanned) { 
       SpannableString sp = new SpannableString(text + " "); 
       TextUtils.copySpansFrom((Spanned) text, 0, text.length(), Object.class, sp, 0); 
       return sp; 
      } else { 
       return text.toString() + " "; 
      } 
     } 
    } 

    @Override 
    public int findTokenStart(CharSequence text, int cursor) { 

     int i = cursor; 

     while (i > 0 && text.charAt(i - 1) != '@') { 
      i--; 
     } 

     if (i < 1 || text.charAt(i - 1) != '@') { 
      return cursor; 
     } 

     return i; 
    } 

    @Override 
    public int findTokenEnd(CharSequence text, int cursor) { 

     int i = cursor; 
     int len = text.length(); 

     while (i < len) { 
      if (text.charAt(i) == ' ') { 
       return i; 
      } else { 
       i++; 
      } 
     } 

     return len; 

    } 
}); 

Il TextWatcher, anche dalla soluzione della questione precedente:

private TextWatcher filterTextWatcher = new TextWatcher() { 

    @Override 
    public void onTextChanged(CharSequence s, int start, int before, int count) { 

     Layout layout = editStatusUpdate.getLayout(); 
     int pos = editStatusUpdate.getSelectionStart(); 
     int line = layout.getLineForOffset(pos); 
     int baseline = layout.getLineBaseline(line); 

     int bottom = editStatusUpdate.getHeight(); 

     editStatusUpdate.setDropDownVerticalOffset(baseline - bottom); 

    } 

    @Override 
    public void beforeTextChanged(CharSequence s, int start, int count, 
      int after) { 

    } 

    @Override 
    public void afterTextChanged(Editable s) { 

    } 
}; 

Per il mio ArrayList:

public class getFriends { 

    String friendID; 
    String friendName; 
    String friendProfile; 

    boolean selected; 

    // SET FRIENDS ID 
    public void setFriendID(String friendID) { 
     this.friendID = friendID; 
    } 

    // GET FRIENDS ID 
    public String getFriendID() { 
     return friendID; 
    } 

    // SET FRIENDS NAME 
    public void setFriendName(String friendName) { 
     this.friendName = friendName; 
    } 

    // GET FRIENDS NAME 
    public String getFriendName() { 
     return friendName; 
    } 

    // SET FRIENDS PROFILE 
    public void setFriendProfile(String friendProfile) { 
     this.friendProfile = friendProfile; 
    } 

    // GET FRIENDS PROFILE 
    public String getFriendProfile() { 
     return friendProfile; 
    } 
} 
+0

Non ho guardato il codice di altre domande, ma sembra che il metodo 'toString' venga chiamato per la classe' getFriends' (nomi uggiosi tra l'altro).Prova ad aggiungere un metodo 'toString' sovrascritto alla classe' getFriends', ad esempio: '@Override public String toString() {return friendName;}' e guarda cosa succede. – Luksprog

+0

Primo. La soluzione nel commento ha funzionato subito. Quindi per favore aggiungi questo come risposta e lo accetterò (con la taglia insieme) :-). Secondo. Quale sarebbe un modo migliore per nominare la classe? Quando dici orribile, solleva qualche problema per il malfunzionamento dell'app? O è solo una cattiva pratica di denominazione? –

+1

Ho esagerato usando "orribile", non c'è alcun problema con il funzionamento dell'app in modo corretto, è solo che dovresti usare le convenzioni java (lettera maiuscola per il nome della classe). Inoltre, forse 'getFriends' non è una buona opzione, ad esempio quando ho letto per la prima volta la tua domanda' getFriends' sembrava più come un nome di metodo e non come una classe. Come classe è un titolare di dati un nome come "FriendData" o "FriendInformation" potrebbe essere stato un nome più espressivo per qualcuno che legge il tuo codice. Questo non è qualcosa di cruciale, ma se hai altre persone a leggerlo, aiutali a capire il codice. – Luksprog

risposta

6

A giudicare dalla in uscita compare che il codice chiama il metodo toString sugli oggetti getClass per recuperare i dati necessari. Come si desidera il nome dell'amico è necessario implementare il proprio metodo toString (sovrascrivendo esso) come questo:

@Override 
public String toString() { 
    return friendName; 
} 
+1

Questo non è come dovrebbe essere fatto (e direi anche che è sbagliato), ci sono metodi designati per questa conversione. Non si deve fare affidamento sul metodo toString delle funzioni. – Heinrisch

14

Si dovrebbe ignorare convertResultToString(Object resultValue) nel filtro, in cui oggetto è la classe. Ciò rende possibile creare una stringa personalizzata per la classe senza fare affidamento sull'override del metodo String.

+2

questa dovrebbe essere la risposta accettata. Funziona meglio con l'internazionalizzazione in quanto non è necessario ottenere il contesto dell'applicazione nell'oggetto del modello. – alaeri

Problemi correlati