在Android TextView中真正地使文本顶部对齐

7 浏览
0 Comments

在Android TextView中真正地使文本顶部对齐

我正在尝试在Android中显示一个TextView,使得视图中的文本顶部对齐:

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    // 创建容器布局
    FrameLayout layout = new FrameLayout(this);
    // 创建文本标签
    TextView label = new TextView(this);
    label.setTextSize(TypedValue.COMPLEX_UNIT_PX, 25);     // 文本高度为25像素
    label.setGravity(Gravity.TOP + Gravity.CENTER);        // 文本顶部居中对齐
    label.setPadding(0, 0, 0, 0);                          // 无内边距
    Rect bounds = new Rect();
    label.getPaint().getTextBounds("gdyl!", 0, 5, bounds); // 测量文本高度
    label.setText("good day, world! "+bounds.top+" to "+bounds.bottom);
    label.setTextColor(0xFF000000);                  // 黑色文本
    label.setBackgroundColor(0xFF00FFFF);                  // 蓝色背景
    // 定位文本标签
    FrameLayout.LayoutParams layoutParams = 
            new FrameLayout.LayoutParams(300, 25, Gravity.LEFT + Gravity.TOP);
                                                            // 文本高度为25像素
    layoutParams.setMargins(50, 50, 0, 0);
    label.setLayoutParams(layoutParams);
    // 组合屏幕
    layout.addView(label);
    setContentView(layout);
}

这段代码输出以下图片:

![enter image description here](https://i.stack.imgur.com/p7UBN.png)

需要注意的地方:

- 蓝色框的高度为25像素,与要求相同

- 文本的高度根据要求也报告为25像素(6 - (-19) = 25)

- 文本不从标签的顶部开始,而是在其上方有一些内边距,忽略了setPadding()

- 这导致文本在底部被裁剪,即使框实际上足够高

如何告诉TextView将文本从框的顶部开始显示?

对于可能的答案,我有两个限制条件:

- 我确实需要保持文本顶部对齐,所以如果有一些将其底部对齐或垂直居中的技巧,我不能使用它,因为我有一些TextView比实际需要的更高的场景。

- 我有点关注兼容性,所以如果可能的话,我想使用早期Android API中可用的调用(最好是1,但绝对不能超过7)。

0
0 Comments

在Android的TextView中,文本的对齐方式是由布局类android.text.Layout来实现的。在绘制文本时,使用了canvas.drawText方法,并且计算了垂直偏移量lbaseline。lbaseline的计算公式是当前行底部减去字体的下降值。lbaseline的计算依赖于getLineTop和getLineDescent两个抽象方法,这两个方法的具体实现可以在BoringLayout类中找到。在BoringLayout的init方法中,根据includepad的值计算了spacing和mBottom/mDesc的值。includepad是一个布尔类型的变量,用于指定文本是否包括额外的padding来适应超出指定上升值的字形。如果includepad为true(默认值),文本的基线将使用字体度量中的top值。否则,文本的基线将使用字体度量中的descent值。根据上述信息,我们可以通过设置includepad来解决文本对齐的问题。但是,实际上这样做并不能得到预期的结果。问题的原因是字体报告的ascent值为-23.2,而边界框报告的top值为-19。也许这是字体的一个“bug”,或者可能是故意这样设计的。无论如何,FontMetrics并没有提供与边界框报告的19相匹配的任何值,即使你试图在字体点数的72dpi和屏幕分辨率240dpi之间进行转换。因此,我们可以通过设置垂直padding来解决这个问题,具体的解决方法有两种。一种是在includepad为true的情况下设置垂直padding,另一种是将includepad设置为false并设置垂直padding。需要注意的是,设置includepad为false并不是唯一有效的解决方法,这两种方法都可以实现相同的效果,只是在转换浮点数到整数时所产生的舍入误差略有不同。选择哪种方法取决于具体的字体和字号,可以根据实际情况调整垂直padding的计算方法。在使用自定义的TextView时,可以通过重写setTextSize方法并根据新大小对一些具有代表性的字符进行getTextBounds来获得最大的top边界,然后根据这个值来设置padding。还需要注意的是,如果使用了自定义的字体,可能会出现某些字符无法完全显示的问题,因此需要对所有将在应用程序中使用的字符进行测试。在某些情况下,可以通过设置TextView的位置偏移和添加额外的padding来解决问题。另外,如果在文本上使用了阴影效果,需要确保阴影不会超出TextView的范围,以避免裁剪。最后,如果想要自动调整文本的大小以适应TextView的限制,可以参考提供的库,但是需要注意一些特殊情况下的问题。

0
0 Comments

问题的原因是TextView的文本无法完全显示在标签内部。解决方法有两种:

方法一:检查父布局与TextView之间是否有足够的空间。可以在父布局底部添加padding,然后查看是否可以显示完整的文本。

例如:如果TextView位于一个FrameLayout中,但是FrameLayout太小,导致TextView被裁剪。可以给FrameLayout添加padding来查看是否可以解决问题。

FrameLayout.LayoutParams layoutParams = new FrameLayout.LayoutParams(300, 50, Gravity.LEFT + Gravity.TOP);

这样可以增加框的大小,并为文本提供足够的空间来显示。

或者,可以添加以下代码:

label.setIncludeFontPadding(false);

这将移除字体周围的填充,并使文本可见。但是,这种方法无法完全显示像'g'这样的字母,因为它们会超出线条。如果确实想要解决这个问题,可能需要微调框的大小或文本的大小。

方法二:使用`setIncludeFontPadding(false)`来移除字体周围的填充,以使文本可见。但是,这种方法无法完全显示像'g'这样的字母,因为它们会超出线条。可以尝试通过调整其他部分来解决这个问题。

以上是解决Android TextView文本无法垂直居中的问题的方法。希望对您有帮助!

0