簡體   English   中英

Android自定義視圖沒有重新繪制,雖然正在調用onDraw

[英]Android custom view not repainting, though onDraw is being called

我有一個名為ArrowView自定義視圖。

當這個視圖是布局的一部分時,它是ArrayAdapter一部分,一切都很好。 (它被重新繪制為基礎數據更改。)

當我使用相同的布局作為另一個Adapter的一部分時, ArrowView不會重新繪制。

我調試了它,發現onDraw 調用,具有不同的rot值,當我預期它時 - 它只是屏幕沒有更新。

我是否需要更改我的ArrowView正確重新繪制?

public class ArrowView extends View {

    private Path path;
    public final Paint paint;
    public final Paint circlePaint;
    private float rot = 30;
    private float length = 0.5f;
    private float width = 1.0f;
    public final static int SIZE = 96;
    private float size = SIZE;
    private float xOff;
    private float yOff;

    public ArrowView(Context context, AttributeSet attrs) {
        super(context, attrs);

        path = new Path();
        path.moveTo( 0.0f,  -0.5f);
        path.lineTo( 0.5f,   0.0f);
        path.lineTo( 0.25f,  0.0f);
        path.lineTo( 0.25f,  0.5f);
        path.lineTo(-0.25f,  0.5f);
        path.lineTo(-0.25f,  0.0f);
        path.lineTo(-0.5f,   0.0f);
        path.close();

        paint = new Paint();
        paint.setARGB(150, 0, 150, 0);

        circlePaint = new Paint();
        circlePaint.setARGB(50, 150, 150, 150);
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        canvas.save();
        canvas.translate(xOff, yOff);
        canvas.scale(size, size);
        canvas.save();
        canvas.translate(0.5f, 0.5f);
        canvas.drawCircle(-0.0f, -0.0f, 0.5f, circlePaint);
        canvas.save();
        canvas.rotate(rot, 0.0f, 0.0f);
        canvas.save();
        canvas.scale(width, length);
        canvas.drawPath(path, paint);
        canvas.restore();
        canvas.restore();
        canvas.restore();
        canvas.restore();
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {

        //Get the width measurement
        int widthSize = getMeasurement(widthMeasureSpec,
                SIZE);

        //Get the height measurement
        int heightSize = getMeasurement(heightMeasureSpec,
                SIZE);

        size = min(widthSize, heightSize) * 0.9f;
        xOff = 0.0f;
        yOff = 0.05f * size;

        //MUST call this to store the measurements
        setMeasuredDimension(widthSize, heightSize);
    }

    public static int getMeasurement(int measureSpec, int contentSize) {
        int specMode = View.MeasureSpec.getMode(measureSpec);
        int specSize = View.MeasureSpec.getSize(measureSpec);
        int resultSize = 0;
        switch (specMode) {
            case View.MeasureSpec.UNSPECIFIED:
                //Big as we want to be
                resultSize = contentSize;
                break;
            case View.MeasureSpec.AT_MOST:
                //Big as we want to be, up to the spec
                resultSize = min(contentSize, specSize);
                break;
            case View.MeasureSpec.EXACTLY:
                //Must be the spec size
                resultSize = specSize;
                break;
        }

        return resultSize;
    }

    public void setLength(float length) {
        this.length = length;
        invalidate();
    }

    public float getLength() {
        return length;
    }

    public void setWidth(float width) {
        this.width = width;
        invalidate();
    }

    public void setRot(float rot) {
        this.rot = rot;
        invalidate();
    }

}

當我想從非ui線程和片段更新視圖時,我也遇到了同樣的問題; invalidate()方法不更新視圖。 所以根據sdk參考

http://developer.android.com/intl/es/reference/android/view/View.html postInvalidate()將解決此問題。

這可以通過兩種方式或更多方式完成!!!

在setter方法中調用runOnUi線程

runOnUiThread(new Runnable() {
    public void run() {
     this.length = length;
    this.invalidate();
    }
});

或者只需在setter方法中調用postInvalidate()

如果調用onDraw()但視圖不自行更新,原因可能是在錯誤的線程上調用它。

在您的適配器中,請確保從UI線程處理您的視圖

 getActivity().runOnUiThread(new Runnable() {
    @Override
    public void run() {
    mAdapter.updateRot(newRot);
 });

 public void updateRot(double newRot){
     arrowView.setRot(newRot);
     notifyDataSetChanged();
 }

從適配器使用notifyDataSetChanged()刷新視圖

notifyDataSetChanged():通知附加的觀察者基礎數據已更改,反映數據集的任何視圖都應刷新自身。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM