java– 在Android TextView中真正顶对齐文本

java– 在Android TextView中真正顶对齐文本,第1张

概述我试图在Android中显示TextView,使视图中的文本顶部对齐:@OverrideprotectedvoidonCreate(BundlesavedInstanceState){super.onCreate(savedInstanceState);//CreatecontainerlayoutFrameLayoutlayout=newFrameLayout(this);//Createtextlab

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

@OverrIDeprotected voID onCreate(Bundle savedInstanceState) {    super.onCreate(savedInstanceState);    // Create container layout    FrameLayout layout = new FrameLayout(this);    // Create text label    TextVIEw label = new TextVIEw(this);    label.setTextSize(TypedValue.COMPLEX_UNIT_PX, 25);     // 25 pixels tall    label.setGravity(Gravity.top + Gravity.CENTER);        // Align text top-center    label.setpadding(0, 0, 0, 0);                          // No padding    Rect bounds = new Rect();    label.getPaint().getTextBounds("gdyl!", 0, 5, bounds); // Measure height    label.setText("good day, world! "+bounds.top+" to "+bounds.bottom);    label.setTextcolor      (0xFF000000);                  // Black text    label.setBackgroundcolor(0xFF00FFFF);                  // Blue background    // position text label    FrameLayout.LayoutParams layoutParams =             new FrameLayout.LayoutParams(300, 25, Gravity.left + Gravity.top);                                                            // also 25 pixels tall    layoutParams.setmargins(50, 50, 0, 0);    label.setLayoutParams(layoutParams);    // Compose screen    layout.addVIEw(label);    setContentVIEw(layout);}

此代码输出以下图像:

需要注意的事项:

>蓝色框高25像素,就像要求一样
>文本边界也按要求报告为25像素高(6 – (-19)= 25)
>文本不是从标签的顶部开始,而是在其上方有一些填充,忽略了setpadding()
>这导致文本被剪切在底部,即使盒子在技术上足够高

如何告诉TextVIEw启动文本顶部的文本?

我对可能的答案有两个限制:

>我确实需要保持文本顶部对齐,所以如果有一些底部对齐或垂直居中的技巧,我不能使用它,因为我有一些场景,其中TextVIEw比它需要的更高是.
>我有点兼容性怪,所以如果可能的话,我想坚持使用早期AndroID API中的调用(最好是1,但绝对不高于7).

解决方法:

TextViews在画布上使用抽象类android.text.Layout到draw the text:

canvas.drawText(buf, start, end, x, lbaseline, paint);

垂直偏移lbaseline计算为线的底部减去字体的下降:

int lbottom = getLineTop(i+1);
int lbaseline = lbottom - getLineDescent(i);

两个调用函数getlinetop和getlineDescent都是抽象的,但是可以在BoringLayout中找到一个简单的实现(go figure … :),它只返回mBottom和mDesc的值.这些在其init方法中计算如下:

if (includepad) {    spacing = metrics.bottom - metrics.top;} else {    spacing = metrics.descent - metrics.ascent;}if (spacingmult != 1 || spacingadd != 0) {    spacing = (int)(spacing * spacingmult + spacingadd + 0.5f);}mBottom = spacing;if (includepad) {    mDesc = spacing + metrics.top;} else {    mDesc = spacing + metrics.ascent;}

这里,includepad是一个布尔值,指定文本是否应包含额外的填充以允许延伸超过指定上升的字形.它可以通过TextVIEw的setIncludeFontPadding方法设置(如@ggc指出的那样).

如果将includepad设置为true(默认值),则文本的位置将由字体度量标准的top-field给出.否则,文本的基线取自descent-field.

因此,从技术上讲,这应该意味着我们需要做的就是关闭IncludeFontpadding,但不幸的是,这会产生以下结果:

原因是字体报告-23.2作为其上升,而边界框报告的顶值为-19.我不知道这是字体中的“BUG”还是应该是这样的.不幸的是,FontMetrics没有提供与边界框报告的19相匹配的任何值,即使您尝试以某种方式合并报告的240dpi的屏幕分辨率与72dpi的字体点定义,因此没有“官方”方式解决这个问题.

但是,当然,可用的信息可用于破解解决方案.有两种方法可以做到:

>将IncludeFontpadding单独保留,即设置为true:

double top = label.getPaint().getFontMetrics().top;label.setpadding(0, (int) (top - bounds.top - 0.5), 0, 0);

即垂直填充被设置为补偿从文本边界和字体度量的最高值报告的y值的差异.结果:

>将IncludeFontpadding设置为false:

double ascent = label.getPaint().getFontMetrics().ascent;label.setpadding(0, (int) (ascent - bounds.top - 0.5), 0, 0);label.setIncludeFontpadding(false);

即垂直填充被设置为补偿从文本边界和字体度量的上升值报告的y值的差异.结果:

请注意,将IncludeFontpadding设置为false并不奇怪.两个版本都应该有效.当字体度量的浮点值转换为整数时,它们产生不同结果的原因是舍入错误略有不同.恰好在这种特殊情况下,IncludeFontpadding设置为false会更好看,但对于不同的字体或字体大小,这可能会有所不同.调整顶部填充的计算可能相当容易,以产生与BoringLayout使用的计算相同的精确舍入误差.我还没有这样做,因为我宁愿使用“无错误”的字体,但如果我找到一些时间,我可能会在以后添加它.然后,IncludeFontpadding是设置为false还是true应该是真的无关紧要.

总结

以上是内存溢出为你收集整理的java – 在Android TextView中真正顶对齐文本全部内容,希望文章能够帮你解决java – 在Android TextView中真正顶对齐文本所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/web/1116138.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-29
下一篇 2022-05-29

发表评论

登录后才能评论

评论列表(0条)

保存