ben*_*n75 8 android canvas textview
我有一个自定义TextView,它的onDraw方法被覆盖,在文本视图周围绘制一个红色边框.
当我将引力 设置为除左边以外的其他东西并且 singleLine = true时:不绘制边框.
以下屏幕截图说明了问题:第二个textView没有边框

TL表示TOP | LEFT; C表示CENTER; SL意味着单行; T意味着真实; F表示错误
这是代码(可以复制/粘贴和运行 - 不需要布局文件)
import android.app.Activity;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.os.Bundle;
import android.view.Gravity;
import android.widget.RelativeLayout;
import android.widget.TextView;
public class MyActivity extends Activity {
private final int TEXT_VIEW_WIDTH_PX = 400;
private final int TEXT_VIEW_HEIGHT_PX = 60;
private Paint borderPaint = new Paint();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
RelativeLayout rootView = new RelativeLayout(this);
getWindow().setContentView(rootView);
borderPaint.setColor(Color.RED);
MyTextView text1 = makeTextView("Grav=TL ; SL=F",100);
rootView.addView(text1);
MyTextView text2 = makeTextView("Grav=C ; SL=T",200);
//combination of the 2 following attributes cause the issue
text2.setSingleLine(true);
text2.setGravity(Gravity.CENTER);
rootView.addView(text2);
MyTextView text3 = makeTextView("Grav=C ; SL=F",300);
text3.setGravity(Gravity.CENTER);
rootView.addView(text3);
MyTextView text4 = makeTextView("Grav=TL ; SL=T",400);
text4.setSingleLine(true);
rootView.addView(text4);
}
/**
* Custom TextView with red border
*/
private class MyTextView extends TextView {
private MyTextView(Context context) {
super(context);
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
canvas.drawLine(1,1,1,TEXT_VIEW_HEIGHT_PX-1,borderPaint);
canvas.drawLine(1,1,TEXT_VIEW_WIDTH_PX-1,1,borderPaint);
canvas.drawLine(TEXT_VIEW_WIDTH_PX-1,1,TEXT_VIEW_WIDTH_PX-1,TEXT_VIEW_HEIGHT_PX-1,borderPaint);
canvas.drawLine(1,TEXT_VIEW_HEIGHT_PX-1,TEXT_VIEW_WIDTH_PX-1,TEXT_VIEW_HEIGHT_PX-1,borderPaint);
}
}
/**
* create a MyTextView with 'text' context and located at x=50 ; y=marginTop
* (nothing relevant for the issue here)
*/
private MyTextView makeTextView(String text, int marginTop){
MyTextView textView = new MyTextView(this);
textView.setText(text);
RelativeLayout.LayoutParams lp = new RelativeLayout.LayoutParams(TEXT_VIEW_WIDTH_PX,TEXT_VIEW_HEIGHT_PX);
lp.topMargin = marginTop;
lp.leftMargin = 50;
textView.setLayoutParams(lp);
return textView;
}
}
Run Code Online (Sandbox Code Playgroud)
感谢pskink的深入研究(来自对我的另一个答案的评论):
如果你想知道为什么自定义
onDraw不绘制任何东西,只需要Log.d的值canvas.getMatrix().[它]似乎画布被翻译/水平滚动(至少在我的情况下)左边8159像素,所以调用
canvas.translate(8159, 0)修复了问题,当然8159不是一个神奇的数字,可以变化.我发现它,看到
VERY_WIDE常数TextView,它设置为16384(2**14),在我的情况下TextView宽度为66,现在(16384-66)/ 2 == 8159,瞧!...但是VERY_WIDE是私有的,所以你无法访问它:-(
从这里开始,我想知道是否可以通过编程方式检索偏移量,并确保它可以轻松实现getScrollX().这种方法通过取消水平滚动来转换画布而不是"黑客"单行.它更自然地显示单行.
内部定制TextView:
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
// translate the canvas before drawing onto it, fixing the position
canvas.translate(getScrollX(), 0);
canvas.drawLine(1, 1, 1, TEXT_VIEW_HEIGHT_PX - 1, borderPaint);
canvas.drawLine(1, 1, TEXT_VIEW_WIDTH_PX - 1, 1, borderPaint);
canvas.drawLine(TEXT_VIEW_WIDTH_PX - 1, 1, TEXT_VIEW_WIDTH_PX - 1,
TEXT_VIEW_HEIGHT_PX - 1, borderPaint);
canvas.drawLine(1, TEXT_VIEW_HEIGHT_PX - 1, TEXT_VIEW_WIDTH_PX - 1,
TEXT_VIEW_HEIGHT_PX - 1, borderPaint);
}
Run Code Online (Sandbox Code Playgroud)
此代码尚未针对所有情况进行彻底测试.我只确认了OP提供的4个案例
| 归档时间: |
|
| 查看次数: |
748 次 |
| 最近记录: |