SpannableStringBuilder setSpan не работает с арабским текстом

Я пытаюсь создать арабскую строку, содержащую пространственные символы разного цвета, текст должен быть черным, а специальные символы - красными, а между предложениями - разные размеры. Как это:

введите здесь описание изображения

Это мое определение TexView:

<com.neopixl.pixlui.components.textview.TextView
    android:id="@+id/sura"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:textSize="@dimen/kuran_sure_text_size"
    android:textDirection="rtl"
    pixlui:typeface="fatih_araz_font.ttf"/>

И это мой код:

SpannableStringBuilder ssb = new SpannableStringBuilder();

for (int i = 0;  i < contentJsonArray.length(); ++i) {
    JSONObject suraJson = (JSONObject)contentJsonArray.get(i);
    Log.d(LOG_TAG, "QuranPageFragment - WebServiceClient.getVerse - success - " +
            "Content " + i + " = " + suraJson.toString());
    ssb.append(suraJson.getString(KEY_VERSE));
    int start = ssb.length();

    if (i == contentJsonArray.length() - 1)
        break;

    // This has to be red and small but it doesn't
    ssb.append(" (#) ");
    ssb.setSpan(new ForegroundColorSpan(R.color.Red), start, ssb.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
    ssb.setSpan(new AbsoluteSizeSpan(10, true), start, ssb.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
}

Log.d(LOG_TAG, "QuranPageFragment - WebServiceClient.getVerse - success - Sura = " + ssb.toString());
suraTextView.setText(ssb, TextView.BufferType.SPANNABLE);

Я пробовал решения для следующего вопроса, но все еще не могу сделать " (#) " красным и маленьким:

SpannableStringBuilder для создания строки с несколькими шрифтами/размерами текста и т.д. Пример?

Может кто-нибудь мне помочь?

ОБНОВИТЬ:

Ни один из них не делает текст красным:

ssb.setSpan(new ForegroundColorSpan(0xFF0000), start, ssb.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
ssb.setSpan(new ForegroundColorSpan(0xFF0000), start, ssb.length(), 0);
ssb.setSpan(new ForegroundColorSpan(getResources().getColor(R.color.Red)), start, ssb.length(), 0);

Это тоже не работает:

SpannableStringBuilder ssb = new SpannableStringBuilder();

for (int i = 0;  i < contentJsonArray.length(); ++i) {
    JSONObject suraJson = (JSONObject)contentJsonArray.get(i);
    Log.d(LOG_TAG, "QuranPageFragment - WebServiceClient.getVerse - success - " +
            "Content " + i + " = " + suraJson.toString());
    Spannable spannable = new SpannableString(suraJson.getString(KEY_VERSE) + " (#) ");

    if (i == contentJsonArray.length() - 1)
        break;

    spannable.setSpan(
            new ForegroundColorSpan(
                    getResources().getColor(R.color.Red)),
            spannable.length() - 5,
            spannable.length(),
            Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
    spannable.setSpan(
            new AbsoluteSizeSpan(10, true),
            spannable.length() - 5,
            spannable.length(),
            Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
    ssb.append(spannable);
}

Log.d(LOG_TAG, "QuranPageFragment - WebServiceClient.getVerse - success - Sura = " + ssb.toString());
suraTextView.setText(ssb);

РЕШЕНО:

Я решил это. Проблема была с библиотекой PixUI, которую я использовал для загрузки собственного арабского шрифта. Когда я удалил его, setSpan работал. Я переключился на библиотеку Calligraphy, чтобы загрузить собственный шрифт.

Следующий код и макет отлично работают:

<TextView
    android:id="@+id/sura"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:textSize="@dimen/kuran_sure_text_size"
    android:textDirection="rtl"/>

SpannableStringBuilder ssb = new SpannableStringBuilder();

for (int i = 0;  i < contentJsonArray.length(); ++i) {
    JSONObject suraJson = (JSONObject)contentJsonArray.get(i);
    Log.d(LOG_TAG, "QuranPageFragment - WebServiceClient.getVerse - success - " +
            "Content " + i + " = " + suraJson.toString());
    ssb.append(suraJson.getString(KEY_VERSE));

    if (i == contentJsonArray.length() - 1)
        break;

    int start = ssb.length();
    ssb.append(" (#) ");
    ssb.setSpan(new ForegroundColorSpan(R.color.Red), start, ssb.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
    ssb.setSpan(new AbsoluteSizeSpan(10, true), start, ssb.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
}

Log.d(LOG_TAG, "QuranPageFragment - WebServiceClient.getVerse - success - Sura = " + ssb.toString());
CalligraphyTypefaceSpan typefaceSpan =
        new CalligraphyTypefaceSpan(
                TypefaceUtils.load(getActivity().getAssets(),
                        "fonts/fatih_araz_font.ttf"));
ssb.setSpan(typefaceSpan, 0, ssb.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
suraTextView.setText(ssb);

Результат:

введите здесь описание изображения

@pskink ты был прав насчет цветового кода. Он должен быть в форме 0xAARRGGBB


person Olcay Ertaş    schedule 17.06.2015    source источник
comment
Что значит Не работает? расскажите нам о проблеме, с которой вы столкнулись. Поделитесь трассировкой logcat на случай возникновения ошибки.   -  person Vinothkumar Arputharaj    schedule 17.06.2015
comment
R.color.Red неверно, это должно быть что-то вроде целого числа 0xAARRGGBB, а не идентификатора цвета   -  person pskink    schedule 17.06.2015
comment
проверьте это руководство takeoffandroid.com/uncategorized/   -  person Chandru    schedule 17.06.2015
comment
Не работает значит не красный и маленький.   -  person Olcay Ertaş    schedule 17.06.2015
comment
цвет должен быть объявлен как-то вроде getResources().getColor(R.color.Red);   -  person Chandru    schedule 17.06.2015
comment
ssb.setSpan(новый ForegroundColorSpan(getResources().getColor((R.color.Red)), start, ssb.length(), 0);   -  person Chandru    schedule 17.06.2015
comment
Замените Spannable.SPAN_EXCLUSIVE_EXCLUSIVE на 0.   -  person Chandru    schedule 17.06.2015
comment
0xFFFF0000, а не 0xFF0000   -  person pskink    schedule 17.06.2015
comment
@pskink, насколько я знаю, единственная разница между 0xFFFF0000 и 0xFF0000 заключается в прозрачности. Оба они должны сделать его красным.   -  person Olcay Ertaş    schedule 17.06.2015
comment
альфа == 0 означает, что цвет вообще не виден   -  person pskink    schedule 17.06.2015
comment
Голосующий против, можете ли вы объяснить, почему вы проголосовали против?   -  person Olcay Ertaş    schedule 17.06.2015


Ответы (1)


Используйте Calligraphy вместо PixUI. Вот зависимость Gradle для него:

compile 'uk.co.chrisjenx:calligraphy:2.1.0'

Используйте TextView, а не какие-то пользовательские TextView, такие как PixUI TextView.

<TextView
    android:id="@+id/sura"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:textSize="@dimen/kuran_sure_text_size"
    android:textDirection="rtl"/>

Примените пользовательский шрифт после создания результирующего текста:

SpannableStringBuilder ssb = new SpannableStringBuilder();

for (int i = 0;  i < contentJsonArray.length(); ++i) {
    JSONObject json = (JSONObject)contentJsonArray.get(i);
    ssb.append(json.getString(KEY_SOME_KEY));

    if (i == contentJsonArray.length() - 1)
        break;

    int start = ssb.length();
    ssb.append("( # )");
    ssb.setSpan(new ForegroundColorSpan(R.color.Red), start, ssb.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
    ssb.setSpan(new AbsoluteSizeSpan(10, true), start, ssb.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
}

CalligraphyTypefaceSpan typefaceSpan =
        new CalligraphyTypefaceSpan(
                TypefaceUtils.load(getActivity().getAssets(),
                        "fonts/some_custom_font.ttf"));
ssb.setSpan(typefaceSpan, 0, ssb.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
textView.setText(ssb);

Используйте цветовой код для ForegroundColorSpan, например 0xAARRGGBB, как предложил @pskink:

ssb.setSpan(new ForegroundColorSpan(0xFFFF0000), start, ssb.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
person Olcay Ertaş    schedule 17.06.2015