web-dev-qa-db-ja.com

複数のタイプサイズのTextViewで行の高さを調整する方法は?

Spannable文字列を保持するTextViewがあります。文字列には一連のテキストが含まれ、最初のWordは文字列の残りの2倍の文字サイズです。

問題は、最初のワードのサイズが大きくなるため、最初の行と2番目の行の間の行間隔が後続の行の間の行間隔よりもはるかに大きくなることです。

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を修正するにはどうすればよいですか?

25
emmby

次のTextViewプロパティのいずれかを使用してみてください。

Android:lineSpacingMultiplier
Android:lineSpacingExtra

少なくともすべての行を同じ高さにしようとします(最初の行と同じ)。

43
Rangel Reale

多くの試行錯誤の後、私は非常にハッキーな解決策を得ました:

  1. テキスト内のすべてのスペースに、強調されたWordと同じ2倍のテキストサイズのスパンナブルを追加しました。このようにして、TextView全体が同じ(大きな)行間隔になります。スパナブルは再利用できないことに注意してください。

  2. 次に、TextViewに負のlineSpacingExtraを指定して、行間が再び見栄えがよくなるようにしました。

  3. テキストサイズの増加による不自然に広いスペースを避けるために、すべてのスペースにScaleXSpanを追加し、元の大きなサイズの50%に拡大しました。

このメソッドは、ローカライズされた文字列(強調されたWordが表示される位置や行の長さがわからない)を保持するTextViewでも機能します。

2
miracula

私はこの関数を書きました:

[〜#〜]入力[〜#〜]

  • LinearLayout ll:

    「TexView」となるレイアウト(方向が垂直であることを確認してください)

  • 文字列のお金:

    変更したい文字列(あなたの場合はより大きなテキストサイズ)

  • 文字列テキスト:

    テキスト

  • コンテキスト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);
}

[〜#〜]ノート[〜#〜]

私はそれをテストしていません...より複雑なものに使用し、それは機能していました...少し調整する必要があるかもしれません。

1
Sherif elKhatib

私はあなたができないと思います:(。Android osはフォントサイズに応じて行間のギャップを計算するので、「30 $」は行1と行2の間のギャップを大きくし、私はしませんこのギャップサイズを制御できるかどうかを確認してください。

これを解決するには、LinearLayuotを簡単に拡張して、向きを垂直に配置します。幅にfillparentを使用して2つのテキストビューを配置するよりも...

そしてfunctionを実装するより、setNoGapText(String s);としましょう。 、およびこの関数では、上部のテキストビューに収まるテキストを測定できます(これはtextutilsで実行できます)。残りのテキストはtextview2に収まります...

このテキストビューの間では、パディングとマージンのプロパティを操作できるため、行間のギャップは想像どおりに見えます。

0
Lukap