2013-08-02 5 views
11

Sto facendo qualche ricerca sulla possibilità di modificare l'interfaccia utente in modo dinamico in base alla direzione di un testo. Sebbene Google supporti le lingue RTL (riferimento: Native RTL support in Android 4.2) ma non copre una situazione in cui l'applicazione presenta un mix di contenuti LTR e RTL.Come ottenere la direzione del testo in Android e modificare il layout in modo dinamico in base alla direzione?

La soluzione di Google è giusta se abbiamo un'app multilingue e ha diverse fonti di dati statici (come voci di menu) in diverse lingue. Tuttavia, non ho trovato nessun altro documento riguardo a come modificare il layout in modo dinamico in base alla direzione del contenuto del testo.

L'immagine seguente mostra il design corrente della mia app di prova. La lista proviene da Facebook (lista dei miei amici) e contiene nomi inglesi e persiani.

enter image description here

La mia soluzione è avere due layout (uno per LTR e uno per RTL) in adattatore e assegnando ad ogni uno basato sulla direzione di nome. Così, ho scritto seguenti righe di codice:

@Override 
    public View getView(final int position, View convertView, ViewGroup parent) { 
     ViewHolder holder; 

      if(position % 2 == 0) 
       convertView = myInflater.inflate(R.layout.list_add_friends_row, null); 
      else 
       convertView = myInflater.inflate(R.layout.list_add_friends_row_mirror, null); 

      holder = new ViewHolder(); 

      holder.llSection = (LinearLayout) convertView.findViewById(R.id.section); 
      holder.tvUserName = (TextView) convertView.findViewById(R.id.tvUserName); 
      holder.ivPicture = (ImageView) convertView.findViewById(R.id.ivPicture); 
      holder.btnAdd = (Button) convertView.findViewById(R.id.btnAdd); 

      convertView.setTag(holder); 



     holder.btnAdd.setTag(position); 
     holder.tvUserName.setText(userList.get(position).getName()); 
     imageDownloader.displayImage(holder.ivPicture, userList.get(position).getPhotoUrl()); 

     ... 

     return convertView; 
    } 

e il risultato è:

enter image description here

ho specchiato righe in base a se fila è pari o dispari. Ora, la mia domanda è come rispecchiare l'interfaccia utente in base al nome. Penso che dovrei cambiare la condizione della clausola da if(position % 2 == 0) a qualcosa come if(isNameLTR(FIRST_CHAR_OF_NAME)). Non ho idea di come implementare questo metodo.

Come posso sapere che un carattere è LTR o RTL? (penso che Android sappia che il primo carattere di parola è RTL o LTR è per questo che quando la larghezza della vista del testo è uguale a quella del padre allinea il testo a destra se il carattere è RLT e a sinistra se il carattere è LTR).

Qualsiasi suggerimento o commento sarebbe apprezzato. Grazie

risposta

22

Solution, è stato più facile che stavo pensando :) Grazie a JAVA

c'è Bidi classe. Questa classe ha getBaseLevel() method che restituisce 0 se il testo è sinistro-a-destra altrimenti 1 (se da destra a sinistra).

Quindi, questo è il mio codice:

@Override 
    public View getView(final int position, View convertView, ViewGroup parent) { 
     ViewHolder holder; 

     Bidi bidi = new Bidi(userList.get(position).getName(), Bidi.DIRECTION_DEFAULT_LEFT_TO_RIGHT); 
     if(bidi.getBaseLevel() == 0) 
      convertView = myInflater.inflate(R.layout.list_add_friends_row, null); 
     else 
      convertView = myInflater.inflate(R.layout.list_add_friends_row_mirror, null); 

... 

e il risultato è il seguente:

enter image description here

=============

Aggiornamento:

C'è un altro metodo, baseIsLeftToRight() che potrebbe essere meglio essere usato in istruzione if. Il risultato era come sopra.

Bidi bidi = new Bidi(userList.get(position).getName(), Bidi.DIRECTION_DEFAULT_LEFT_TO_RIGHT); 
if(bidi.baseIsLeftToRight()) 
       convertView = myInflater.inflate(R.layout.list_add_friends_row, null); 
      else 
       convertView = myInflater.inflate(R.layout.list_add_friends_row_mirror, null); 
0

Usa textAlignment con gravity per ottenere tutti i testi DESTRA o SINISTRA

android:gravity="right" 
android:textAlignment="gravity" 
0

Se il testo è in una TextView, allora tutto ciò che dovete fare è

android:textDirection="anyRtl" 

per forzare RTL. Guarda le altre opzioni per i tuoi requisiti.

Ci possono essere casi in cui il testo misto non deve essere mostrato in un TextView. Ad esempio, il testo può essere passato in una condivisione Intent a Gmail o WhatsApp e così via. In questi casi, è necessario utilizzare una combinazione delle seguenti classi:

Come citato nella documentazione, questi sono ...

classe Utility [es] per la formattazione del testo da visualizzare in un contesto potenzialmente direzionale di direzione senza garbling. La direzionalità del contesto è impostata alla creazione del formatter e la direzionalità del testo può essere stimata o passata quando è conosciuta.

Così, per esempio, che tu abbia un String che ha una combinazione di inglese & arabo, ed è necessario il testo ad essere

  • da destra a sinistra (RTL).
  • sempre allineato a destra, anche se la frase inizia con l'inglese.
  • inglese & parole arabe nella sequenza corretta e senza garbling.

allora si potrebbe raggiungere questo obiettivo utilizzando il metodo unicodeWrap() come segue:

String mixedLanguageText = ... // mixed-language text 

if(BidiFormatter.getInstance().isRtlContext()){ 
    Locale rtlLocale = ... // RTL locale 
    mixedLanguageText = BidiFormatter.getInstance(rtlLocale).unicodeWrap(mixedLanguageText, TextDirectionHeuristics.ANYRTL_LTR); 
} 

Questo sarebbe convertire la stringa in RTL e allinearlo a sinistra, se anche un solo carattere RTL-lingua era nella stringa e fallback in LTR altrimenti. Se si desidera che la stringa sia RTL anche se è completamente inserita, ad esempio inglese (una lingua LTR), è possibile utilizzare TextDirectionHeuristics.RTL anziché TextDirectionHeuristics.ANYRTL_LTR.

Questo è il modo corretto di gestire il testo con direzione mista in assenza di TextView. È interessante notare come gli stati di documentazione,

noti anche che queste euristiche direzione corrispondono agli stessi tipi di costanti forniti nella classe View per setTextDirection(), come TEXT_DIRECTION_RTL.

Ulteriori riferimenti:

1.Write text file mix between arabic and english.

2.Unicode Bidirectional Algorithm.