Как настроить высоту строки в TextView с несколькими размерами шрифта? - PullRequest
25 голосов
/ 15 июня 2010

У меня есть TextView, который содержит Spannable строку.Строка содержит набор текста, первое слово которого в два раза больше размера шрифта, чем остальная часть строки.

Проблема заключается в том, что межстрочный интервал между первой и второй строкой намного больше межстрочного интервала.между последующими строками из-за увеличенного размера первого слова.

http://img.skitch.com/20100615-fwd2aehbsgaby8s2s9psx3wwii.png

Составляемая строка была создана с использованием следующего фрагмента кода:

    // Price
    CharSequence text = "$30 Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua."
    final Pattern priceRegex = Pattern.compile("^(.[0-9]+)\\s.*");
    final Matcher m = priceRegex.matcher(text!=null ? text : "");
    if( m.matches() ) {
        text = new SpannableString(text);
        ((SpannableString)text).setSpan(new RelativeSizeSpan(2), 0, m.end(1), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
    }

Как можноЯ исправил свой TextView так, чтобы все строки имели одинаковый интервал?

Ответы [ 4 ]

43 голосов
/ 29 декабря 2011

Вы можете попробовать использовать одно из следующих свойств TextView:

android:lineSpacingMultiplier
android:lineSpacingExtra

, чтобы хотя бы попытаться сделать все строки одинаковой высоты (такой же, как первая).

2 голосов
/ 08 августа 2014

После долгих проб и ошибок я получил очень хакерское решение:

  1. Я добавил в каждый пробел внутри текста spannables с таким же удвоенным размером текста, как у выделенного слова.,Таким образом, весь TextView получил одинаковый (большой) межстрочный интервал.Имейте в виду, что вы не можете повторно использовать spannable.

  2. Затем я дал TextView отрицательный lineSpacingExtra, чтобы межстрочный интервал снова выглядел хорошо.

  3. Чтобы избежать необычно больших пробелов из-за увеличенного размера текста, я добавил ScaleXSpan к каждому пробелу, масштабируя их до 50% от их первоначального большого размера.

Этот метод должен работать даже для TextViews, которыеудерживайте локализованные строки (там, где вы никогда не знаете, в каком месте появляется выделенное слово или какова длина вашей строки), пока каждая строка содержит хотя бы один пробел.

1 голос
/ 29 июля 2011

Я написал эту функцию:

ВХОД

  • LinearLayout ll:

    Макет, который будет вашим "TexView" (убедитесь, что его ориентация вертикальная)

  • Струнные деньги:

    Строка, которую вы хотите отличать (в вашем случае больший размер текста)

  • Текст строки:

    текст

  • Context mContext

    контекст

ЧТО ДЕЛАТЬ

Я прокомментировал части, которые вы должны отредактировать


private void populateText(LinearLayout ll,
        String money, String text , Context mContext) { 
    String [] textArray = text.split(" ");
    Display display = getWindowManager().getDefaultDisplay();
    ll.removeAllViews();
    int maxWidth = display.getWidth() - 20;

    LinearLayout.LayoutParams params; // to be used over and over
    LinearLayout newLL = new LinearLayout(mContext);
    newLL.setLayoutParams(new LayoutParams(LayoutParams.FILL_PARENT,
            LayoutParams.WRAP_CONTENT));
    newLL.setGravity(Gravity.LEFT);
    newLL.setOrientation(LinearLayout.HORIZONTAL);

    int widthSoFar = 0;

    ///FIRST INSERT THE MONEY TEXTVIEW
    LinearLayout LL = new LinearLayout(mContext);
    LL.setOrientation(LinearLayout.HORIZONTAL);
    LL.setGravity(Gravity.CENTER_HORIZONTAL|Gravity.BOTTOM); //THIS IS IMPORTANT TO keep spacing up not down
    LL.setLayoutParams(new ListView.LayoutParams(
            LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT));

    TextView TV = new TextView(mContext);
    TV.setText(money);
    //TV.setTextSize(size);  <<<< SET TEXT SIZE
    TV.measure(0, 0);
    params = new LinearLayout.LayoutParams(TV.getMeasuredWidth(),
            LayoutParams.WRAP_CONTENT);
    //params.setMargins(5, 0, 5, 0);  // YOU CAN USE THIS
    LL.addView(TV, params);
    LL.measure(0, 0);
    widthSoFar += TV.getMeasuredWidth();// YOU MAY NEED TO ADD THE MARGINS
    newLL.addView(LL, params);

    for (int i = 0 ; i < textArray.length ; i++ ){
        LL = new LinearLayout(mContext);
        LL.setOrientation(LinearLayout.HORIZONTAL);
        LL.setGravity(Gravity.CENTER_HORIZONTAL|Gravity.BOTTOM);
        LL.setLayoutParams(new ListView.LayoutParams(
                LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT));

        TV = new TextView(mContext);
        TV.setText(textArray[i]);
        //TV.setTextSize(size);  <<<< SET TEXT SIZE
        TV.measure(0, 0);
        params = new LinearLayout.LayoutParams(TV.getMeasuredWidth(),
                LayoutParams.WRAP_CONTENT);
        //params.setMargins(5, 0, 5, 0);  // YOU CAN USE THIS
        LL.addView(TV, params);
        LL.measure(0, 0);
        widthSoFar += TV.getMeasuredWidth();// YOU MAY NEED TO ADD THE MARGINS
        if (widthSoFar >= maxWidth) {
            ll.addView(newLL);

            newLL = new LinearLayout(mContext);
            newLL.setLayoutParams(new LayoutParams(
                    LayoutParams.FILL_PARENT,
                    LayoutParams.WRAP_CONTENT));
            newLL.setOrientation(LinearLayout.HORIZONTAL);
            newLL.setGravity(Gravity.LEFT);
            params = new LinearLayout.LayoutParams(LL
                    .getMeasuredWidth(), LL.getMeasuredHeight());
            newLL.addView(LL, params);
            widthSoFar = LL.getMeasuredWidth();
        } else {
            newLL.addView(LL);
        }
    }
    ll.addView(newLL);
}

Примечание

Я не проверял это ... Я использовал его для более сложных вещей, и он работал ... Возможно, вам придется немного подправить.

0 голосов
/ 29 июля 2011

Я думаю, что вы не можете :(. Android OS вычисляет промежутки между строками в соответствии с размером шрифта, так что «30 $» делает разрыв между строкой 1 и строкой 2 больше, и я не знаю, если этоМожно контролировать размер этого промежутка.

Чтобы решить эту проблему, вы можете легко расширить LinearLayuot и установить вертикальную ориентацию. Чем поместить 2 текстовых просмотра с fillparent для ширины ....

и затем реализовать функцию, скажем, setNoGapText (String s); и в этой функции вы можете измерить текст, который может поместиться в текстовом представлении сверху (это можно сделать с помощью textutils), а затем остальной текст будет помещен в textview2...

между этим текстовым представлением вы можете поиграть со свойствами padding и margins, чтобы промежутки между строками выглядели так, как вы их себе представляете.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...