调用invalidate后,Android Custom View显示纯黑色

时间:2016-05-31 17:23:17

标签: android android-canvas android-custom-view android-relativelayout

在这段代码中,我想在两个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()后,自定义视图显示为纯黑色是否有任何理由?

2 个答案:

答案 0 :(得分:2)

通常,系统会自动处理小部件的大小调整,隐藏,显示和大量其他内容,但如果绘制的像素或后备数据的底层缓冲区已更改或过时(您交换图像资源,则有时会出现问题)视图或原始数据集更改)。发生这种情况是因为操作系统无法知道数据是以特定方式更改的。

在这些你正在处理绘图的情况下,你必须告诉系统它的底层数据与Widget.invalidate()并没有处于良好状态,并且重新绘制在主线程上排队,就像你提到的那样。根据系统实现和Android版本,系统更改跟踪的内容会有所不同,但我通常会假设系统资源(字节数组,字符数组,资源索引,上下文中的手动绘图)不会被跟踪,需要使用无效其他一切都将由系统处理。

来源:When it's necessary to execute invalidate() on a View?

答案 1 :(得分:0)

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

我认为你在做什么是在将更新设置为true之前调用它 - 所以你的onDraw方法通过声音的错误更新运行。