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

问题描述 投票:0回答:9

拨打

TextView.setTextSize()
工作异常。在调用
setTextSize
之后,如果我们得到
getTextSize
,它会返回一个比我们之前设置的值高得多的值。

这就是我们正在做的:

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

有人见过这个吗?

android textview
9个回答
380
投票

这里的区别在于,在

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

21
投票

发生此问题是因为

getTextSize()
方法返回的像素大小取决于屏幕密度!要获取实际 TextSize 使用此:

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

我希望它能解决这个问题:)


8
投票

如果设置改变字体大小,导致显示错误,可以这样做:

setTextSize(TypedValue.COMPLEX_UNIT_DIP, 15.f);

6
投票

困扰了很久终于这样解决了

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>

5
投票

当我们尝试使用 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));

4
投票

简而言之,如果你想缩小文字大小

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

因为 getTextSize() 返回 UNIT_PX,那么我们应该使用 UNIT_PX


3
投票

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中)。

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

@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的尺寸,那么它将接收字体缩放两次


0
投票

字体大小基于屏幕尺寸

public static void applyFont(TextView tv, Float fontSize) {
    tv.setTextSize(TypedValue.COMPLEX_UNIT_PX, fontSize * fontFactor);
}

public static float fetchFontFactor(Activity act) {

    DisplayMetrics displayMetrics = new DisplayMetrics();

    act.getWindowManager().getDefaultDisplay().getMetrics(displayMetrics);

    float returnFactor = ((float) displayMetrics.widthPixels ) / 1280.0f;

    return returnFactor;
}

在 MainActiviy.java 中我有

fontFactor = fetchFontFactor(this);

现在的问题是,我的代码中的 1280 是什么。

答案是,这只不过是设计师提供的设计宽度。前任。如果设计师给出的设计尺寸是1080x1920,你可以把1280换成1080。

所以如果设计师在设计中使用了55的字体,我们可以使用55,如下所示。

applyFont(titleTV, 55f);

这适用于两个方向...

© www.soinside.com 2019 - 2024. All rights reserved.