Android - 在TextView中绘制线条

时间:2013-10-14 22:59:11

标签: java android textview

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

123456
213456
214356
124365

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

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

到目前为止我尝试了什么: 我扩展了一个TextView类并覆盖了onDraw(Canvas)方法并试图让某些东西工作并设法显示垂直的蓝线,但无法连接数字2。我不确定android决定何时调用onDraw(),因为我不会在我的代码中调用它,但我宁愿我可以这样控制它何时显示行。

2 个答案:

答案 0 :(得分: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

简单不是吗?

答案 1 :(得分:0)

这只是一个想法:

你有什么:

  • 鉴于文字大小可以说:20px

  • 视图的X和Y坐标。

  • TextView(如果有)

  • 为内容提供重力
  • px中的文字大小。 getTextSize()paint.measureText(); [画布上的rect.right是文字大小]

  • 文字ems。 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")),则测量的宽度将是近似值,绝对值为“2”的x坐标。相对于其父母可能要复杂得多。

编辑: 我上面写的内容可以使用paint.[getTextBounds()][1]方法轻松获得,该方法会为您Rect提供Point