我需要在画布上绘制一些文字。我已经在画布中添加了一个矩形框,我的目标是使这个文本适合框,但无论我尝试什么,文本永远不适合所有屏幕尺寸。
另一件事是这个文本是简单的HTML。
TextView currDateLabel = new TextView(getContext());
currDateLabel.layout(0, 0, boxSize.x, boxSize.y);
currDateLabel.setTextSize(TypedValue.COMPLEX_UNIT_PX, getResources().getDimensionPixelSize(R.dimen.label_date));
currDateLabel.setTextColor(Color.WHITE);
currDateLabel.setText(Html.fromHtml("Dec 11<sup><small><small>TH</small></small></sup>"));
currDateLabel.setDrawingCacheEnabled(true);
Bitmap dateBitmap = currDateLabel.getDrawingCache(true);
// I've also tried setting the width of this Bitmap but it doesn't seem to do anything
this.canvas.drawBitmap(dateBitmap, boxPosition.x, boxPosition.y, null);
所以在这里解释一些变量:
boxSize
是一个Point
对象,用于存储画布上框的宽度和高度。 这些值似乎对TextView
的大小没有影响,因为我可以看到文字超出了框。
boxPosition
是一个Point
对象,用于在画布上存储该框的x
和y
位置。
R.dimen.label_date
是dimens.xml
个文件中的值。
我创建了多个dimens.xml
个文件(values/dimens.xml
,values-hdpi/dimens.xml
,values-xhdpi/dimens.xml
等等)
我以为我可以测试大多数屏幕尺寸,并计算每个屏幕类别的文字大小。但是它没有按照我的预期工作。
这些值适用于 Samsung Galaxy S8 :
屏幕宽度:1440,屏幕高度:2768
屏幕密度:4.0
屏幕密度DPI:640
屏幕缩放密度:4.0
这些值适用于 Samsung Galaxy S7 :
屏幕宽度:1440,屏幕高度:2560
屏幕密度:4.0
屏幕密度DPI:640
屏幕缩放密度:4.0
它们都属于XXXHDPI
类别,因此它们具有相同的字体大小,但Galaxy S8文本适合框,而Galaxy S7文本太大而且不在框内。
我在这里错过了什么吗?
在Canvas上绘制HTML文本有什么完全不同的方法吗?
更详细地解释我的用例:
我指的是一个SVG / Vector对象。
label_down.xml
:
<?xml version="1.0" encoding="utf-8"?>
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="90dp"
android:height="45dp"
android:viewportWidth="90"
android:viewportHeight="45">
<path
android:fillColor="?attr/labelColor"
android:pathData="M 0 0 L 0 37.532 L 36.63 37.532 L 45 45 L 53.371 37.532 L 90 37.532 L 90 0 Z" />
</vector>
然后我从该向量创建一个Bitamp
对象,并在Canvas上绘制Bitmap
。
VectorDrawableCompat vectorDrawableCompat = VectorDrawableCompat.create(getContext().getResources(), R.drawable.label_down, theme);
Bitmap bitmap = Bitmap.createBitmap(vectorDrawableCompat.getIntrinsicWidth(), vectorDrawableCompat.getIntrinsicHeight(), Bitmap.Config.ARGB_8888);
this.canvas.drawBitmap(bitmap, someXPos, someYPos, null);
这样做会产生以下结果:
现在,我的目标是在该框内创建文本。
希望这更有意义。
答案 0 :(得分:1)
我认为这指出了“sp”和“dp”单位之间的差异。您没有在问题中记录维度文件中Template.instance().editType.set(false);
Template.instance().editZip.set(!template.editZip.get());
Template.instance().editHeadCount.set(false);
Template.instance().editDate.set(false);
Template.instance().editTime.set(false) ;
Template.instance().editDuration.set(false);
的值。我假设,因为它是一个文本大小的单位,你使用“sp”单位。
如果是这样,请将“xxsp”更改为“xxdp”以检查是否有差异。我刚刚在Nexus 5X API 26仿真器和运行Android 7.0的Galaxy S7上试用了这个,而“dp”单元修复了HTML文本的问题。这就是我所看到的:
Nexus 5X API 26仿真器
Galaxy S7 Device API Android 7.0
更新:我很好奇究竟发生了什么。在S7设置中,可缩放像素(SP)的缩放系数看起来大于1。转到“设置 - &gt;显示 - &gt;屏幕缩放和字体”,并将“FONT SIZE”设置为第三个哈希标记。你的文字现在可以正确显示。
您不希望文本独立于图形进行缩放,因此,IMO使用与密度无关的像素(DP)作为文本的单位,这是保持图形和文本之间一致性的正确方法。
第二次更新:对于给定的屏幕尺寸/密度,只要图形的大小固定并且显示的字体大小可以根据设备设置而改变,您将继续有可能文本不适合。如果您不认为将与密度无关的像素指定为字体的单位,则可以继续使用可缩放像素,但调整代码中使用的字体大小。像这样:
function turnOffSelect(currentDiv) {
var divArray = ['.editType', '.editZip', '.editHeadCount', '.editDate', '.editTime', '.editDuration' ]
for (i = 0; i < divArray.length; i++) {
if (divArray[i] != currentDiv) {
Template.instance().eval(divArray[i]).set(false);
}
}
}
这会将字体的有效缩放系数调整回1.0。这里的缺点是虽然你可能会说,label_date
字体大小,但实际显示的大小会有所不同,并且会小于同样为float fontScale = getResources().getConfiguration().fontScale;
textview.setTextSize(TypedValue.COMPLEX_UNIT_PX, getResources()
.getDimensionPixelSize(R.dimen.label_date_sp) / fontScale);
的其他元素。这与指定“DP”具有相同的效果,但将使用更标准的“SP”单位。
答案 1 :(得分:0)
HTML文本无法正常呈现,我建议将DOM对象绘制到画布中