0

我有一个应用程序,它接收用户的输入,然后单击按钮以如下格式显示计算结果:

123456
213456
214356
124365

我需要一条线(最好是蓝色的)来加入列表中的每个数字 2,因为它们沿着 TextView 向下移动。

如果用户不想要,我还需要选择不使用此行。

到目前为止我所尝试的: 我扩展了一个 TextView 类并覆盖了 onDraw(Canvas) 方法,并试图让某些东西正常工作并设法显示垂直的蓝线,但无法获得数字 2 的加入。我不确定android如何决定何时调用onDraw(),因为我没有在我的代码中调用它,但我宁愿我可以控制它何时显示线条。

4

2 回答 2

0

我会这样进行。

  • 用户输入值并单击按钮
  • 当点击按钮时,隐藏 TextView 并将其替换为 ImageView 或保留 TextView 并将 ImageView 放在 TextView 的顶部(TextView 上 ImageView 的重叠可以通过 FrameLayout 实现
  • 在 ImageView 中绘制 OnDraw() 方法中的线条和数字
  • 当用户点击 ImageView 时,隐藏 ImageView 并再次显示 TextView。

最后,如果 2 的位置是固定的,则不需要测量文本。如果位置不固定,您可以将数字放入数组中。这是一些混合顺序的代码(未经测试)

var resStr1 = Integer.toString(resultNumber);
var position = 0;

...
// METHOD 1, multiple 2's in a number
var j = 0;
for (int i = 0; i < resStr1.length(); i++){

    char c = s.charAt(i);
    if (c == '2') {
        position[j] = i;
        j++;
    }
}

// METHOD 2. ONLY ONE 2 in a number
position = resStr1.indexOf('2');



// CONTINUE
...
Paint p = new Paint();
...
float left = customMarginLeft + p.measureText(resStr1.substring(0, position)); 
float top = customMarginTop;
...
canvas.drawRect( bla bla bla...
drawText() // ??

如果您也想获得文本高度,还可以查看 getTextBounds()。

关于 onDraw 方法,不要管它会被系统调用多少时间,如果性能很关键,只需保持包含结果的变量的范围和全局预计算,将属性和方法放在主类中控制绘图方法的行为。每当另一个元素与您的控件重叠或系统中发生某些事情时,系统将一次又一次地重绘线条,因此一次又一次调用 onDraw 的事实是正常的,否则您的线条将不会再次重绘并且可能会消失如果发生任何事情,请从屏幕上显示。当然上面的代码也可以放在自定义控件(组合控件)中。

要清除这些行,您应该调用 invalidate() 或 postInvalidate() 方法。此方法将清除整个区域并强制再次调用 onDraw()。然后全局放置一个标志,如

shouldRedrawLines = false;

并在 onDraw() 中执行以下操作:

if (shouldRedrawLines) { // please note that the onDraw is called again and again and this condition allows you to check if in another part of the program you decided to clear the lines
    DrawLines();  // contains the code for redrawing lines
}
DrawNumbersFromResult(); // contains the code for redrawing Numbers

简单不?

于 2013-10-15T00:21:59.230 回答
0

这只是想法:

你有什么:

  • 给定文本大小让我们说:20px

  • 视图的 X 和 Y 坐标。

  • 提供给内容的重力(TextView如果有的话)

  • 以 px 为单位的文本大小。getTextSize()paint.measureText();[rect.right on Canvas 是文字大小]

  • 短信。getEms()

  • 可选:填充或边距(如果有)

你需要找到什么:

  • 画布上每个字母的每个 x 坐标。

  • 画布上每个字母的每个 y 坐标。

如何:

  • x = 文本中的字母位置 * 字体大小(或 ems)。如果有填充或边距,则向 x 添加填充左侧 + 右侧填充;[画布上的rect.left是x]

  • 重置每个新行的字母位置

  • y = 行号 * 字体大小(或 ems)。+ 上边距 + 下边距 [画布上的 rect.bottom 为 y]

  • 收集所有近似 x 和 y 以形成Point.

  • 匹配每Point一个onDraw()

如果您认为要使用paint.measureText("13332", 0, "13332".indexOf("2")),测量的宽度将是近似的并且绝对是其自身的 x 坐标“2”。相对于其父级而言,查找起来可能要复杂得多。

编辑:我上面写的内容可以很容易地使用paint.[getTextBounds()][1]方法获得,这会给你Rect一个你可以形成一个Point

于 2013-10-15T00:55:15.280 回答