TextView.setTextSizeが異常に動作する-さまざまな画面でテキストビューのテキストサイズを動的に設定する方法


119

通話TextView.setTextSize()が異常に働いています。呼び出しの直後に、以前に設定した値よりもはるかに高い値が返されるsetTextSize場合getTextSize

これが私たちがしていることです:

zoomControl.setOnZoomInClickListener(new OnClickListener() {
    public void onClick(View view) {
        float size = mViewShabad.getTextSize() + 1;
        textView.setTextSize(size);
    }
});

誰かこれを見たことがある?


2
2つの異なるオブジェクトのテキストサイズを取得および設定していますか?
シェリルサイモン、

回答:


359

ここでの違いは、setTextSize(int size)メソッドでは、デフォルトの単位タイプが「sp」または「スケーリングされたピクセル」であることです。この値は、画面密度ごとに異なるピクセル寸法になります(ldpi、mdpi、hdpi)。

getTextSize()一方、テキストの実際のピクセル寸法を返します。

を使用setTextSize(int unit, float size)して単位タイプを指定できます。この定数値はTypedValueクラスにありますが、一部は次のとおりです。

TypedValue.COMPLEX_UNIT_PX   //Pixels

TypedValue.COMPLEX_UNIT_SP   //Scaled Pixels

TypedValue.COMPLEX_UNIT_DIP  //Device Independent Pixels

それを見つけて、ここに投稿しようとしていました。どうもありがとう!
singhspk

1
実際にはTypedValue(単数)である必要があると思います。インポートはandroid.util.TypedValueです。
Hein du Plessis、2011年

5
また、注意が必要なのは、APIレベル7でこれを開始したことだけです。
mxcl、2012

3
引数の順序に注意することが重要です-誤って推測した順序だったため、誤ってsetTextSize(size、TypedValue.COMPLEX_UNIT_SP)がありました。
マーク

1
興味深いことに、私のGalaxy NexusのICSでは、setTextSize(14、TypedValue.COMPLEX_UNIT_SP)を使用しても効果はありませんでした(デフォルトのサイズを使用したため)。私は自分の間違いに気付いたときにJelly Beanのバグを報告しようとしていました!
マーク・

20

この問題は、getTextSize()メソッドが画面の密度に応じてピクセル単位でサイズを返すために発生しました。実際のTextSizeを取得するには、これを使用します。

DisplayMetrics metrics;
metrics = getApplicationContext().getResources().getDisplayMetrics();
float Textsize =myTextView.getTextSize()/metrics.density;
myTextView.setTextSize(Textsize+1);

それが解決することを願っています:)


2
私はと表示メトリクスを使用して私の問題を解決しましたsetTextSize(int unit, float size)
エドワード・チェンマイ

8

フォントサイズを変更すると、表示エラーが発生します。次のようにします。

setTextSize(TypedValue.COMPLEX_UNIT_DIP, 15.f);

3
誰がtextSizeを設定しDIPますか?
IgorGanapolsky 2015年

4

プログラムでgetTextSize()の問題としてsetText()を実行しようとすると、sp / dp / dipではなくpxで値が返され、1sp / dp = 1.5px(画面サイズ= 240)がわかります。

 titleBar.setTextSize(TypedValue.COMPLEX_UNIT_SP, (getResources().getDimension(R.dimen.text_size)*1.5f)); 

私にとって完璧に機能しているか、displaymatrixとpx:sp / dpの比率を使用して、その値を1.5fに置き換えることができます

means-> titleBar.setTextSize(TypedValue.COMPLEX_UNIT_SP, (getResources().getDimension(R.dimen.text_size)*your_sp_and_px_ratio_in_int f));

3

久しぶりにこれにぶつかり、ようやくこのように解決しました

textView.setTextSize(TypedValue.COMPLEX_UNIT_PX,
          getResources().getDimension(R.dimen.textsize));

次のようなdimenフォルダーを作成しますres / values / dimensions.xml

<?xml version="1.0" encoding="utf-8"?>
<resources>

 <dimen name="textsize">8sp</dimen>

 </resources>

2

つまり、テキストサイズを縮小したい場合

float size = mViewShabad.getTextSize()*1.1f;
textView.setTextSize(TypedValue.COMPLEX_UNIT_PX, size);

getTextSize()はUNIT_PXを返すため、UNIT_PXを使用する必要があります


1

Kotlinソリューション

リソースを使用して設定するには、次のように使用します。

textView.setTextSize(COMPLEX_UNIT_PX, textView.resources.getDimension(R.dimen.my_text_size))

リソース値で同じことを行うには、この拡張プロパティを追加して、テキストサイズをはるかに簡単に設定します

textView.textSizeRes = R.dimen.my_text_size

var TextView.textSizeRes
    get() = textSize.toInt()
    set(@DimenRes textSizeRes) {
        setTextSize(COMPLEX_UNIT_PX, resources.getDimension(textSizeRes))
    }

0

少し混乱したので、この回答に追加のフレーバーを追加しました。あなたこのテストを任意にドロップできるはずです@RunWith(AndroidJUnit4.class)(また、あなたのdimens.xmlにdimensを追加する必要があります)プロジェクトにあなたが持っているテスト。

注:これらのテストはすべて合格です

@Test public void testScaledFontSizes() {
  if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
    final Context context = InstrumentationRegistry.getTargetContext();

    Configuration configuration = context.getResources().getConfiguration();
    configuration.fontScale = 2.0f;
    configuration.densityDpi = 160; // mdpi, 1:1
    context.getResources().updateConfiguration(configuration, null);

    float scaledTextSize = context.getResources().getDimensionPixelSize(R.dimen.sp_15);
    assertEquals(30.0f, scaledTextSize);

    // Create a new TextView with the explicitly set configuration
    TextView textView = new TextView(context);
    textView.setTextSize(TypedValue.COMPLEX_UNIT_PX, scaledTextSize);

    // 30, because font size is scaled
    assertEquals(30.0f, textView.getTextSize());

    // This is what we *don't* want, it's scaled *twice*!
    textView.setTextSize(scaledTextSize);
    assertEquals(60.0f, textView.getTextSize());

    // DP instead of SP tests
    float fifteenDp = context.getResources().getDimensionPixelSize(R.dimen.dp_15);
    assertEquals(15.0f, fifteenDp);

    textView.setTextSize(TypedValue.COMPLEX_UNIT_PX, fifteenDp);
    // Still 15, because it's DP, not SP
    assertEquals(15.0f, fifteenDp);

    textView.setTextSize(fifteenDp);
    // 30, because setTextSize DOES font scaling
    assertEquals(30.0f, textView.getTextSize());
  }
}

私が見つけた大きなポイントTextView.setTextSize(float) は、フォントスケーリング適用することです。そのため、すでにDPではなくSPとラベル付けされている寸法を渡すと、フォントスケーリングを2回受け取ります。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.