2022年4月4日月曜日

TextViewの幅に合わせたテキスト表示

注意

私はjava初心者です、Android Studioも初心者です、はじめて2週間くらいです。拙いメモ書きと思ってください。


先週、TextViewの幅いっぱいに文字列を表示する必要がありまして、急いでいたのでとりあえず検索しました。

setAutoSizeTextTypeWithDefaults(int autoSizeTextType);

とか

<TextView
    ︰
    android:autosizetexttype="uniform">
等で解決するのは、リリース後に知りました(Android 8.0以降)

さて、検索でよく見かけたのが、

PaintのmeasureTextで表示幅を計算、もし大きかったらsetTextSizeのサイズを-1して目標の幅に収まるまで繰り返す。

という方法。

たぶんジワジワと這い寄るのには深い理由がある筈(適当
もしくは文字の最大・最小spやTextViewの幅なんて気にしないロックな設定が必要だからです。
(単純に方法の説明には十分っていうのが最有力説)

当時、流石に-1ずつはコストが高いので類似品を作りました。
尚、ロックな仕様に手直ししてあります。検索汚染になるなら削除します。

float calcTextSize(float widthPixels, String str) {
    if (widthPixels < 1f || str == null || str.length() == 0) return 0f;

    float textSize = 16f;    //適当
    Paint paint = new Paint();
    //paint.setTypeface(Typeface.SERIF);

    //表示幅を超える文字の大きさを求める
    while(true) {
        paint.setTextSize(textSize);
        if ( paint.measureText(str) > widthPixels ) break;
        textSize *= 2f;
    }

    //目標の幅に近づける
    for (float adjust = textSize * 0.5f ; adjust > 0.25f ; adjust *= 0.5f) {
        paint.setTextSize(textSize);
        textSize += paint.measureText(str) > widthPixels ? -adjust : adjust;
    }
    
    return (float)Math.floor(textSize);
}

表示幅と文字列を与えると、テキストサイズとして0f以上を返します。

float f = calcTextSize(1000f, "hogehoge");
textView.setTextSize(TypedValue.COMPLEX_UNIT_PX, f);

ユーザーがフォントサイズを変更した場合でもCOMPLEX_UNIT_PXなら固定表示です。

もっとシンプルになら、こうでしょうか?

float calcTextSize(float widthPixels, String str) {
    float textSize = 128f;
    Paint paint = new Paint();

    for (float adjust = textSize * 0.5f ; adjust > 0.25f ; adjust *= 0.5f) {
        paint.setTextSize(textSize);
        textSize += paint.measureText(str) > widthPixels ? -adjust : adjust;
    }

    return (float)Math.floor(textSize);
}

0 件のコメント:

コメントを投稿

2024年のヤマザキ春のパンまつり

パンまつりが始まったので点数計算 アプリ の更新を行いました。  去年はシールの種類が0.5から2.5点の5種類でしたが、今年は3点シールが復活して6種類です。 (3点シールはダブルソフト専用?) 画像認識に使用するサンプルを購入、プログラムを修正、公開できました。  気が向い...