如何在屏幕方向改变时重新绘制画布中的图形?

3

我的代码在表格或设备旋转之前运行良好。 当旋转时,绘图会被清除,我了解到这是由于设备旋转时活动被重新启动造成的。

我的问题是如何重新绘制并将数据保存到 onSaveInstanceState 中。

许多人说我必须使用 onSaveInstanceState 来保存绘图,但是当我要保存的数据类型是 Path 时,我不知道该怎么做。

以下是我的代码片段:

public class MyDrawView extends View implements OnTouchListener {
    MyDrawView drawView;
    float prevX = 0;
    float prevY = 0;

    private Bitmap mBitmap;
    private Canvas mCanvas;
    private Path mPath;
    private Paint mBitmapPaint;
    private Paint mPaint;
    private int w,h;
    private ArrayList<Path> paths = new ArrayList<Path>();
    private ArrayList<Paint> bitPaints = new ArrayList<Paint>();
    private ArrayList<Paint> pathPaints = new ArrayList<Paint>();
    Paint tempPaint;
    private String filename="";

    public MyDrawView(Context c,String filename) {
        super(c);
        mPath = new Path();
        mBitmapPaint = new Paint(Paint.DITHER_FLAG);


        this.filename=filename;
        setFocusable(true);
        setFocusableInTouchMode(true);
        this.setOnTouchListener(this);
        mPaint = new Paint();
        mPaint.setAntiAlias(true);
        mPaint.setDither(true);
        mPaint.setColor(Color.RED);
        mPaint.setStyle(Paint.Style.STROKE);
        mPaint.setStrokeJoin(Paint.Join.ROUND);
        mPaint.setStrokeCap(Paint.Cap.ROUND);
        mPaint.setStrokeWidth(6);
        tempPaint=new Paint(mPaint);
        mCanvas = new Canvas();
        mPath = new Path();
        if (rotated){
            setDefaultDrawing();
        }

    }
    public void setDefaultDrawing()
    {

    }
    public Bitmap getBitmap(){
        return this.mBitmap;
    }
    public void setStrokeWidth(float width){
        mPaint.setStrokeWidth(width);
    }
    public void setColor(int color){
        mPaint.setColor(color);
    }
    public String getFileName(){
        return this.filename;
    }
    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        super.onSizeChanged(w, h, oldw, oldh);
        this.w=w;
        this.h=h;
        mBitmap = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888);
        mCanvas = new Canvas(mBitmap);
        Path tempPath=new Path(mPath);
        paths.add(tempPath);
        Paint tempPaint=new Paint(mPaint);
        pathPaints.add(tempPaint);
        Paint tempBitPaint=new Paint(mBitmapPaint);
        bitPaints.add(tempBitPaint);
    }

    @Override
    protected void onDraw(Canvas canvas) {
        canvas.drawBitmap(mBitmap, 0, 0, mBitmapPaint);

        canvas.drawPath(mPath, mPaint);
    }

最好在清单文件中修复方向...使用纵向或横向。 - Pragnani
我希望能够轻松地减轻负担,但我必须使其灵活 :) 必须使其在纵向和横向都能正常工作。 - She Smile GM
2个回答

0
我已经想通了,由于Path是一个自定义对象,我创建了一个类对象来保存Path,这样,我可以将该类对象保存在我的onSaveInstanceState中,并使用相同的类对象检索它。

请详细说明一下,如果您还记得的话。 - hypd09
2
如果您有解决方案,应该提供更多细节以帮助他人。您不能只创建一个对象而不将该对象设置为可 Parcelable。这对他人来说是有用的信息。 - pixel

0

对于其他遇到这个问题的人。您需要创建一个包含路径(Path)并且该路径需要实现Parcelable接口的类。

e.g

public static class CustomPath extends Path implements Parcelable {

    private Path path;

    public CustomPath() {

    }

    protected CustomPath(Parcel in) {
        path = (Path) in.readValue(Path.class.getClassLoader());
    }

    @Override
    public int describeContents() {
        return 0;
    }

    @Override
    public void writeToParcel(Parcel dest, int flags) {
        dest.writeValue(path);
    }

    @SuppressWarnings("unused")
    public final Parcelable.Creator<CustomPath> CREATOR = new Parcelable.Creator<CustomPath>() {
        @Override
        public CustomPath createFromParcel(Parcel in) {
            return new CustomPath(in);
        }

        @Override
        public CustomPath[] newArray(int size) {
            return new CustomPath[size];
        }
    };
}

完成这一步后,您需要在Activity方法onSaveInstanceState()中保存CustomPath。

示例

@Override
public void onSaveInstanceState(@NonNull Bundle outState) {
    super.onSaveInstanceState(outState);

    outState.putParcelable("_Canvas", _DrawingView.getPath());
}

然后在您的onViewStateRestored()中恢复先前的Canvas

示例:

    @Override
    public void onViewStateRestored(@Nullable Bundle savedInstanceState) {
       super.onViewStateRestored(savedInstanceState);         
       _DrawingView.setPath(savedInstanceState.getParcelable("_Canvas"));
    }

显然要检查键是否存在以及Bundle不为空。

奖励:如果您的画布大小发生变化,请调整路径大小。添加以下代码:

                    Matrix scaleMatrix = new Matrix();
                    RectF rectF = new RectF();
                    path.computeBounds(rectF, true);
                    scaleMatrix.setScale(1.25f, 1.25f,rectF.centerX(),rectF.centerY());
                    path.transform(scaleMatrix);

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