TextView.setTextSize行为异常-如何为不同的屏幕动态设置Textview的文本大小


119

呼叫TextView.setTextSize()工作异常。在调用setTextSizeif 之后,getTextSize它返回的值比我们先前设置的值高得多。

这是我们正在做的:

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

谁看过这个吗?


2
您正在获取并设置两个不同对象的文本大小吗?
谢丽尔·西蒙

Answers:


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,

5
还需要注意的是,它只是从API级别7开始执行此操作。这是荒谬的API中的另一个“陷阱”。
mxcl 2012年

3
注意参数顺序很重要-我不小心设置了setTextSize(size,TypedValue.COMPLEX_UNIT_SP),因为那是我错误地假定的顺序!
2012年

1
有趣的是,在我的Galaxy Nexus上的ICS上,使用setTextSize(14,TypedValue.COMPLEX_UNIT_SP)无效(因此使用默认大小),但是当我升级到Jelly Bean时,没有显示任何文本(例如0大小)。当我意识到自己的错误时,我正要报告一个果冻豆的错误!
2012年

20

发生此问题是因为该getTextSize()方法返回的像素大小取决于屏幕密度!要获得Actual 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

4

当我们尝试使用getTextSize()以编程方式设置setText()问题时,以px代替sp / dp / dip返回值,并且我们知道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添加到您的dimens.xml中)。

注意:所有这些测试均通过

@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) 应用了字体缩放,因此,如果传入已经被标记为SP而不是DP的dimen thats,它将收到两次字体缩放。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.