用于绘图的Android应用程序中的MVC模式

时间:2012-06-09 07:02:59

标签: java android

我正在开发用于绘图的Android应用程序。所以,我需要使用MVC模式。我有应用程序用于绘图的View类:

public class PainterView extends View implements DrawingListener {

    private Painter painter;

    private Bitmap bitmap;
    private Paint bitmapPaint;
    private Path path;
    private Paint paint;

    public PainterView(Context context, Painter painter) {

        super(context);
        this.painter=painter;
        this.painter.addDrawingListener(this);
    }

    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        super.onSizeChanged(w, h, oldw, oldh);
    }

    @Override
    protected void onDraw(Canvas canvas) {

        if (bitmap!=null) {
            canvas.drawBitmap(bitmap, 0, 0, bitmapPaint);
            canvas.drawPath(path, paint);
        } 
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        float x = event.getX();
        float y = event.getY();

        switch (event.getAction()) {
            case MotionEvent.ACTION_DOWN:
                painter.touchStart(x, y);
                break;
            case MotionEvent.ACTION_MOVE:
                painter.touchMove(x, y);
                break;
            case MotionEvent.ACTION_UP:
                painter.touchUp();
                break;
        }

        return true;
    }

    @Override
    public void update(Bitmap bitmap, Paint bitmapPaint, Path path, Paint paint) {

        this.bitmap=bitmap;
        this.bitmapPaint=bitmapPaint;
        this.path=path;
        this.paint=paint;
        invalidate();
    }
}

主要活动:

public class MainScreenActivity extends Activity {
    /** Called when the activity is first created. */
    private PainterView mMainView;

    @Override
    public void onCreate(Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);
        requestWindowFeature(Window.FEATURE_NO_TITLE);
        Display display = getWindow().getWindowManager().getDefaultDisplay();
        Painter painter=new Painter(display.getWidth(), display.getHeight());
        mMainView = new PainterView(this, painter);
        setContentView(mMainView);
    }
}

和Painter类保持所有算法(模型)。请注意,所有算法都运行良好:

public class Painter {

    private List<DrawingListener> mDrawingListeners;

    private static final float TOUCH_TOLERANCE = 4;
    private static final float MINP = 0.25f;
    private static final float MAXP = 0.75f;

    public Paint mPaint;
    public Bitmap mBitmap;
    public Canvas mCanvas;
    public Path mPath;
    public Paint mBitmapPaint;

    private float mX, mY;

    public Painter(int width, int height) {
        initializeGraphic(width, height);
    }

    private void initializeGraphic(int width, int height) {

        mPaint = new Paint();
        mPaint.setAntiAlias(true);
        mPaint.setDither(true);
        mPaint.setColor(0xFFFF0000);
        mPaint.setStyle(Paint.Style.STROKE);
        mPaint.setStrokeJoin(Paint.Join.ROUND);
        mPaint.setStrokeCap(Paint.Cap.ROUND);
        mPaint.setStrokeWidth(12);

        mBitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
        mCanvas = new Canvas(mBitmap);
        mPath = new Path();
        mBitmapPaint = new Paint(Paint.DITHER_FLAG);

        mCanvas.drawRect(new Rect(0, 0, width, height), new Paint(Color.BLACK));
    }

    private void drawingChanged() {
        notifyDrawingListeners();
    }

    public void touchStart(float x, float y) {
        Log.e("event", "start");
        mPath.reset();
        mPath.moveTo(x, y);
        mX = x;
        mY = y;
        drawingChanged();
    }

    public void touchMove(float x, float y) {
        Log.e("event", "move");
        float dx = Math.abs(x - mX);
        float dy = Math.abs(y - mY);
        if (dx >= TOUCH_TOLERANCE || dy >= TOUCH_TOLERANCE) {
            mPath.quadTo(mX, mY, (x + mX) / 2, (y + mY) / 2);
            mX = x;
            mY = y;
        }
        drawingChanged();
    }

    public void touchUp() {
        Log.e("event", "up");
        mPath.lineTo(mX, mY);
        mCanvas.drawPath(mPath, mPaint);
        mPath.reset();
        drawingChanged();
    }

    public void addDrawingListener(DrawingListener listener) {
        if (mDrawingListeners==null) {
            mDrawingListeners=new ArrayList<DrawingListener>();
        }
        mDrawingListeners.add(listener);
    }   

    public void removeDrawingListener(DrawingListener listener) {
        mDrawingListeners.remove(listener);
    }

    public void notifyDrawingListeners() {

        for (DrawingListener listener:mDrawingListeners) {
            listener.update(mBitmap, mBitmapPaint, mPath, mPaint);
        }
    }
}

但是我有一些问题:当我通过屏幕触摸并绘制然后它可以工作,但如果我从屏幕上抬起手指,那么屏幕将再次变黑!即应用程序不保存绘图结果。所以,如果我将这些行添加到onDraw方法:

@Override
protected void onDraw(Canvas canvas) {

    if (bitmap!=null) {
        canvas.drawBitmap(bitmap, 0, 0, bitmapPaint);
        canvas.drawPath(path, paint);
        painter.mBitmap=bitmap;
        painter.mBitmapPaint=bitmapPaint;
        painter.mPaint=paint;
        painter.mPath=path;
    } 
}

然后它的作品!但我不明白为什么!应用程序使用相同的链接,为什么我需要在绘制后再次更改它?谢谢。

1 个答案:

答案 0 :(得分:1)

Android隐含在MVC模式之后,所以你不必费心。

MVC pattern on Android