Android自定义视图在调用invalidate后显示纯黑色

9
在这段代码中,我想在两个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()后,自定义视图显示为纯黑色的原因是什么?

1
你在哪里将“update”设置为true? - Mobile Developer
我是在我的“CollectingDetail”活动中调用invalidate()之前设置的。也许我会尝试在调用“CollectingDetail”的setArrow()之前调用它。 - Pink Jazz
在最后一行:cacheCanvas.drawPath(p, paint);中,你如何找到p的值? - Khairul Alam Licon
看起来我成功了。将两行代码交换,将update的更改移动到setArrow()之前就解决了问题。我该如何颁发赏金? - Pink Jazz
据我所知,问题在于:您将充气视图的背景设置为透明,但这不是您自定义视图的背景。也许尝试通过调用setBackgroundColor(Color.TRANSPARENT)(不使用v实例)将视图的背景设置为透明。 - racs
2个回答

2
通常情况下,系统会自动处理小部件的调整大小、隐藏显示以及其他许多事情,但是如果绘制像素或后备数据的基础缓冲区已更改或陈旧(您在视图上交换映像资源或原始数据集发生更改),则有时会出现问题。这是因为操作系统无法知道数据以特定方式发生了变化。
在处理绘图时,当你遇到这些情况时,你必须使用Widget.invalidate()告诉系统其底层数据处于不良状态,重新绘制将排队等待在主线程中,就像你所提到的那样。根据系统实现和Android版本,系统跟踪更改的内容会有所不同,但我通常做的是假设系统资源(字节数组、字符数组、资源索引、在上下文中手动绘图)没有被跟踪,并且需要进行无效操作,而其他所有内容都将由系统处理。
来源: When it's necessary to execute invalidate() on a View?

0

正如您所知,invalidate() 用于通过调用 onDraw 更新视图。

我认为您之前是在将更新设置为 true 之前调用了它 - 所以根据声音,您的 onDraw 方法是以错误的更新运行的。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接