【问题标题】:Drawing Custom Size Text on Canvas在画布上绘制自定义大小的文本
【发布时间】:2017-12-18 01:04:10
【问题描述】:

我需要在画布上绘制一些文本。我已经在画布中添加了一个矩形框,我的目标是使该文本适合该框,但无论我尝试什么,文本都无法完美地适合所有屏幕尺寸。

另一件事是该文本是简单的 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 对象,它存储了画布上框的 xy 位置。

  • R.dimen.label_datedimens.xml 文件中的一个值。

我创建了多个dimens.xml 文件(values/dimens.xmlvalues-hdpi/dimens.xmlvalues-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 对象并在画布上绘制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);

这样做会导致如下结果:

现在,我的目标是在该框内创建文本。

希望这更有意义。

【问题讨论】:

  • 我认为应该有一些其他的工作来实现你正在寻找的东西,也许你应该尝试一些其他的东西,而不是制作一个盒子并在那个盒子里绘制一个 html 文本。如果您能解释一下您的任务,那么人们可能会比在那个框中输入文本更能帮助您..只是说
  • @AdeelTurk 我已经用更多细节修改了我的问题。谢谢
  • 我为我的聊天应用程序创建了相同的用户界面。我使用 9.patch 图像作为 textview 背景,它在所有设备和两个方向上都可以正常工作
  • 所以我的意思是你为什么要绘制这个向量然后试图把文本放在这个盒子里你可以用其他方式做对..如果你想要这个 bg 的书面文本的位图然后您可以获取该文本视图的位图并在任何您想要的地方使用它..
  • @AdeelTurk 矢量是更大矢量的一部分,画布上还有很多其他东西。我不能将它全部作为一个位图来完成,因为矢量的某些部分是可点击的,而有些则不是。并且文本会根据用户在应用程序中所做的其他事情而变化,因此它不能只是框/矢量中的静态文本。

标签: android android-canvas textview android-vectordrawable


【解决方案1】:

我认为这指出了“sp”和“dp”单位之间的区别。您没有在问题中记录 label_date 的值在您的尺寸文件中是什么。我假设,因为它是文本大小的单位,所以您使用的是“sp”单位。

如果是这样,请将“xxsp”更改为“xxdp”以检查您是否发现差异。我刚刚在 Nexus 5X API 26 模拟器和运行 Android 7.0 的 Galaxy S7 上进行了尝试,“dp”单元修复了 HTML 文本的问题。这是我看到的:

Nexus 5X API 26 模拟器

Galaxy S7 设备 API Android 7.0

更新:我很好奇到底发生了什么。在 S7 设置中,可缩放像素 (SP) 的缩放因子似乎大于 1。转到“设置->显示->屏幕缩放和字体”并将“字体大小”设置为第三个井号。您的文本现在应该可以正确显示了。

您不希望文本独立于图形进行缩放,因此,IMO 使用与密度无关的像素 (DP) 作为文本单位是保持图形和文本之间一致性的正确做法。

第二次更新:对于给定的屏幕尺寸/密度,只要您的图形尺寸是固定的,并且显示的字体大小可以根据设备设置进行更改,您将继续有可能文本不合适。如果您不认为将与密度无关的像素指定为字体单位,您可以继续使用可缩放像素,但调整代码中使用的字体大小。像这样的:

float fontScale = getResources().getConfiguration().fontScale;
textview.setTextSize(TypedValue.COMPLEX_UNIT_PX, getResources()
    .getDimensionPixelSize(R.dimen.label_date_sp) / fontScale);

这会将字体的有效缩放因子调整回 1.0。这里的缺点是,尽管您可能会指定,比如说,14sp 的字体大小,但实际显示的大小会有所不同,并且会小于同样为14sp 的其他元素。这与指定“DP”具有相同的效果,但将使用更标准的“SP”单位。

【讨论】:

  • 我会对此进行更多研究。但我确实尝试过DP。 DP 的问题是字体大小不会随着分辨率的增大而变大,这就是 SP 的重点。示例:我将 OnePlus 3 手机上的“字体大小”和“显示大小”更改为“小”。这意味着16dp 字体大小在框内将非常小,因为字体不会变大。这可能会起作用,感觉更像是一种解决方法而不是解决方案。
  • @th3pat3l 您可能想查看 Android 8.0 和支持库中提供的 auto sizing。由以 dp 测量的小部件限制的和 sp 小部件的问题是 sp 和 dp 可以相互独立地变化。以 dp 为单位测量的字体应该在更大的屏幕上缩放,就像您的图形小部件一样。
  • 您有一些很棒的想法,您的第二次更新将我引向了一个不同的方向,我能够解决这个问题。我创建了盒子和TextView 作为自定义View。以盒子高度除以 3 为例。这给了我COMPLEX_UNIT_PX(像素)的字体大小。谢谢
【解决方案2】:

如您所见,HTML 文本无法正确呈现,我建议将 DOM 对象绘制到画布中

DOM Elements on Canvas

【讨论】:

  • HTML 文本完美呈现。问题是TextView 的大小太大。但我会看一下链接。谢谢
猜你喜欢
  • 2015-10-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-12-04
  • 1970-01-01
  • 2016-12-13
  • 2021-06-21
  • 1970-01-01
相关资源
最近更新 更多