在这段代码中,我想在两个ImageView的顶部之间画一条线。但是,在运行应用时,自定义视图在调用invalidate()
后显示为纯黑色。
这是我的代码:
public class ArrowView extends RelativeLayout {
public Paint paint;
public Bitmap eraser;
public Canvas cacheCanvas;
public float leftX;
public float leftY;
public float rightX;
public float rightY;
public boolean update = false;
public ImageView iv_leftArrow;
public ImageView iv_rightArrow;
private int w;
private int h;
LayoutInflater mInflater;
public ArrowView(Context context) {
super(context);
this.setWillNotDraw(false);
mInflater = LayoutInflater.from(context);
init();
}
public ArrowView(Context context, AttributeSet attrs) {
super(context, attrs);
this.setWillNotDraw(false);
mInflater = LayoutInflater.from(context);
init();
}
public ArrowView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
this.setWillNotDraw(false);
mInflater = LayoutInflater.from(context);
init();
}
@Override
public void onSizeChanged(int w, int h, int oldW, int oldH) {
this.w = w;
this.h = h;
super.onSizeChanged(w, h, oldW, oldH);
}
public void init() {
View v = mInflater.inflate(R.layout.arrow_view, this, true);
paint = new Paint(Paint.ANTI_ALIAS_FLAG);
paint.setColor(Color.BLACK);
paint.setStrokeWidth(5);
v.setBackgroundColor(Color.TRANSPARENT);
eraser = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888);
iv_leftArrow = (ImageView) v.findViewById(R.id.iv_leftarrow);
iv_rightArrow = (ImageView) v.findViewById(R.id.iv_rightArrow);
cacheCanvas = new Canvas();
cacheCanvas.setBitmap(eraser);
}
public void setCoordinates(float leftX, float leftY, float rightX, float rightY) {
this.leftX = leftX;
this.leftY = leftY;
this.rightX = rightX;
this.rightY = rightY;
}
@Override
public void onDraw(Canvas c) {
super.onDraw(c);
setCoordinates(iv_leftArrow.getX() + iv_leftArrow.getWidth() / 2, iv_leftArrow.getY(), iv_rightArrow.getX() + iv_rightArrow.getWidth() / 2, iv_rightArrow.getY() );
if (update) {
c.drawLine(leftX, leftY, rightX, rightY, paint);
update = false;
}
cacheCanvas.drawPath(p, paint);
}
}
在调用invalidate()
后,自定义视图显示为纯黑色是否有任何理由?
答案 0 :(得分:2)
通常,系统会自动处理小部件的大小调整,隐藏,显示和大量其他内容,但如果绘制的像素或后备数据的底层缓冲区已更改或过时(您交换图像资源,则有时会出现问题)视图或原始数据集更改)。发生这种情况是因为操作系统无法知道数据是以特定方式更改的。
在这些你正在处理绘图的情况下,你必须告诉系统它的底层数据与Widget.invalidate()并没有处于良好状态,并且重新绘制在主线程上排队,就像你提到的那样。根据系统实现和Android版本,系统更改跟踪的内容会有所不同,但我通常会假设系统资源(字节数组,字符数组,资源索引,上下文中的手动绘图)不会被跟踪,需要使用无效其他一切都将由系统处理。
答案 1 :(得分:0)
如您所知,invalidate()用于通过调用onDraw
来更新视图。
我认为你在做什么是在将更新设置为true之前调用它 - 所以你的onDraw
方法通过声音的错误更新运行。