2015-08-27 10 views
7

Ho questa funzione che funziona bene su Android 4.4.1, ma si interrompe su 5.0+.ImageSpan non funziona su Android 5

public static SpannableStringBuilder prependImage(Drawable drawable, String text) { 
    SpannableStringBuilder builder = new SpannableStringBuilder(" " + text); 
    builder.setSpan(new ImageSpan(drawable), 0, 1, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); 
    return builder; 
    } 

e lo uso come questo:

class MyButton extends Button { 

    // ... snip ... 

    setText(
     prependImage(
      getDrawable(imageResource, color),      
      getContext().getString(stringResource)), 
     BufferType.SPANNABLE); 

Ecco il metodo getDrawable() di cui sopra:

private Drawable getDrawable(int resource, int color) { 
    final Resources resources = getContext().getResources(); 
    Drawable drawable = resources.getDrawable(resource); 
    if (drawable != null) { 
     drawable.setColorFilter(color, PorterDuff.Mode.SRC_IN); 
     drawable.setBounds(0, 0, drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight()); 
    } 
    return drawable; 
    } 

Quando metto a punto, tutto sembra avere successo, ma nessuna immagine viene disegnata . Qualche idea su cosa potrei fare male?

+0

ho creato una classe che estende 'android.widget.Button', ha cercato di utilizzare il metodo' prependImage (Drawable, String) 'sull'emulatore con KitKat e l'immagine era * non * disegnato. –

+0

Beh, dovrebbe esserci un modo per farlo disegnare su entrambi. Sono perfettamente felice di buttarlo via e fare qualcos'altro. Ti sei assicurato di impostare i limiti del drawable per essere qualcosa di diverso da 0,0,0,0? –

+0

@i_am_jorf Potresti usare 'TextView' invece di' Button'. Sembra funzionare bene con 'TextView' in tutte le versioni di Android. –

risposta

3

Il codice relativa a lavorare con Spannables è ok. Puoi controllarlo impostando il testo per TextView.

Il problema è nella progettazione materiale del pulsante su Android 5.0.

<style name="Widget.Material.Button"> 
    <item name="background">@drawable/btn_default_material</item> 
    <item name="textAppearance">?attr/textAppearanceButton</item> 
    <item name="minHeight">48dip</item> 
    <item name="minWidth">88dip</item> 
    <item name="stateListAnimator">@anim/button_state_list_anim_material</item> 
    <item name="focusable">true</item> 
    <item name="clickable">true</item> 
    <item name="gravity">center_vertical|center_horizontal</item> 
</style> 

Ci sono due soluzioni.

Il primo è solo utilizzare TextView come pulsante e impostare Testo con l'immagine.

Per un altro (e potrebbe essere più corretto) è necessario estendere stile del tasto (Widget.Material.Button) in modo successivo:

<style name="BtnStyle" parent="android:Widget.Material.Button"> 
    <item name="android:textAppearance">@null</item> 
</style> 

Poi nel layout:

<Button 
    android:id="@+id/test2" 
    android:layout_width="match_parent" 
    android:layout_height="wrap_content" 
    android:text="Test" 
    style="@style/BtnStyle"/> 

Dopo farete dovresti vedere le immagini nel pulsante.

Non dimenticare che per la versione Android inferiore a 5.0 devi creare anche BtnStyle, ma in un'altra directory di risorse (res/values-v14/style.xml).

+0

Questa sembra la soluzione più razionale. Grazie. –

+0

ho visto questo post e mi sono detto "andiamo a mangiare qualche taglia" ma è già risolto – Elltz

0

Forse è necessario controllare il contenuto di tale oggetto Drawable, si usa getDrawable() per ottenere l'oggetto Drawable, ma la definizione dell'API sembra non corrispondere ai parametri di chiamata.

Per Android 5.0+

Drawable getDrawable (int id) Questo metodo è sconsigliata a livello API 22. Uso getDrawable (int, Tema) invece.

getDrawable disegnabile (int id, tema Resources.Theme) Restituisce un oggetto drawable associato a un ID risorsa specifico e progettato per il tema specificato .

Il secondo parametro sembra essere un tema, non un colore. destra ?

+0

Ah, mi dispiace. Ho un metodo privato in 'MyButton' chiamato' getDrawable (int id, int color) 'che racchiude la chiamata a' getContext(). GetResources(). GetDrawable (int id) 'e chiama anche' drawable.setColorFilter (colore, PorterDuff.Mode.SRC_IN); '. Ciò restituisce, a quanto sembra, un drawable perfettamente ragionevole. –

0

provare questo

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { 
     getResources().getDrawable(R.drawable.your_drawable, getTheme()); 
      } else { 
       getResources(). 
         getDrawable(R.drawable.your_drawable); 
      } 
+0

L'uso della nuova versione con parametro tema non ha alcun effetto. –

10

Per impostazione predefinita, nei pulsanti Materiale sono stati creati stili per mostrare il testo in maiuscolo. Tuttavia, c'è un bug nel metodo AllCapsTransformationMethod utilizzato per la maiuscola che lo fa scartare i dati Spannable.

È possibile eseguire l'override dello stile dei pulsanti predefinito e disabilitare le maiuscole specificando android: textAllCaps = "false" sul pulsante.

<Button 
    ... 
    android:textAllCaps="false" /> 

uno sguardo here

+0

Questo risolve il problema! –

+0

Benvenuto! Risposta del segno Pls accettata :-) – Shishram

+1

WTF Android ... Grazie ragazzo –