2015-08-27 3 views
7

У меня есть эта функция, которая отлично работает на Android 4.4.1, но разрывается на 5.0+.ImageSpan не работает на 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; 
    } 

И я использую это так:

class MyButton extends Button { 

    // ... snip ... 

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

Вот getDrawable() метод ссылки выше:

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; 
    } 

Когда я отладки, кажется, что все получится, но изображение не обращается , Любые идеи, что я могу делать неправильно?

+0

Я создал класс, который 'расширяет android.widget.Button', попытался с помощью' prependImage (рисуем, String) 'метод на эмуляторе работает KitKat и изображение было * не * нарисованный. –

+0

Ну, должен быть способ заставить его нарисовать оба. Я совершенно счастлив выбросить это и сделать что-то еще. Удостоверились ли вы, что границы допустимого значения будут чем-то иным, чем 0,0,0,0? –

+0

@i_am_jorf Вы можете использовать 'TextView' вместо' Button'. Кажется, он отлично работает с «TextView» во всех версиях Android. –

ответ

3

Ваш код относящийся к работе с Spannables нормально. Вы можете проверить это, установив текст для TextView.

Проблема в материальном дизайне кнопки на 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> 

Существует два решения.

Первый - это просто TextView как ваша кнопка и setText с изображением на нем.

С другой стороны (и может быть более правильным) вам нужно продлить стиль кнопки (Widget.Material.Button) в следующем виде:

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

Тогда в макете:

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

После вы будете делать вы должны увидеть изображения в кнопке.

Не забывайте, что для версии для Android, которая ниже 5.0, вы также должны создать BtnStyle, но в другом каталоге ресурсов (res/values-v14/style.xml).

+0

Это похоже на наиболее рациональное решение. Благодарю. –

+0

Я видел это сообщение, и я был как «давай пойдём съесть немного щедрости», но его уже решили – Elltz

0

Возможно, вам нужно проверить содержимое этого объекта Drawable, вы используете getDrawable() для получения объекта Drawable, но определение API не соответствует вашим вызывающим параметрам.

Для Android 5.0 и выше

Drawable getDrawable (интермедиат идентификатор) Этот метод был устаревшим в уровне API 22. Использование getDrawable (интермедиат, тема) вместо этого.

Drawable getDrawable (int id, Resources.Theme theme) Возвращает объект , связанный с определенным идентификатором ресурса и созданный для заданной темы .

Второй параметр выглядит как тема, а не цвет. правильно ?

+0

А, извините. У меня есть закрытый метод в 'MyButton', называемый' getDrawable (int id, int color) ', который завершает вызов getContext(). GetResources(). GetDrawable (int id)', а также вызывает 'drawable.setColorFilter (цвет, PorterDuff.Mode.SRC_IN); '. Это возвращает, что выглядит, вполне разумным. –

0

попробовать это

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

Использование новой версии с параметром темы не имеет никакого эффекта. –

10

По умолчанию кнопки «Материал» стилизованы для отображения текста во всех шапках. Однако есть ошибка в методе AllCapsTransformationMethod, используемом для капитализации, который заставляет его отказаться от Spannable data.

Вы можете переопределить стиль кнопки по умолчанию и отключить все шапки, указав андроид: textAllCaps = "false" на вашей кнопке.

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

посмотреть here

+0

Это действительно проблема! –

+0

Ваш прием! Ответ Pls ответ принят :-) – Shishram

+1

WTF Android ... Спасибо парень –

 Смежные вопросы

  • Нет связанных вопросов^_^