0

现在,我正在使用 CustomView 在画布上绘图,我需要将画布(可能作为位图)保存到 FileOutputStream 中,然后移动到具有相同功能的另一个 CustomView。

我不确定我是否应该使用不同的方法来实现这一点,但无论我在做什么,只要我调用 startActivity(i) 就会崩溃。

我的理解是,我的 CustomView 使用 onTouch() 绘制,它绘制到 Path 对象上,然后调用 onDraw(canvas),它在 Canvas 上绘制 Path。(如果我错了,请纠正我)。

此画布是否包含位图对象?还是每次调用 onDraw 都需要写入在 onCreate() 期间创建的单独位图?或者我是否需要为每次调用 onDraw() 创建一个新的临时位图?我已经看到了很多不同的问答,但还没有找到理解。

这是我的主要活动:

公共类 MainActivity 扩展 Activity {

Bitmap pic;
CustomView mCustomView;
OnTouchListener touchListener;
Button eraseButton;
String [] files = { "File1.png", "File2.png", "File3.png" };

int color = Color.BLACK;

RelativeLayout layout;

private Paint paint = new Paint();
private Path path = new Path();

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    layout = (RelativeLayout) findViewById(R.id.layout);
    mCustomView = new CustomView(this);
    //layout.buildDrawingCache(); should I use this?

    layout.addView(mCustomView);

    touchListener = new OnTouchListener() {
        public boolean onTouch(View v, MotionEvent event){
            float eventX = event.getX();
            float eventY = event.getY();

            switch (event.getAction()) {
            case MotionEvent.ACTION_DOWN:
                path.moveTo(eventX, eventY);
                break;
            case MotionEvent.ACTION_MOVE:
            case MotionEvent.ACTION_UP:
                path.lineTo(eventX, eventY);
                break;
            }
            mCustomView.invalidate();
            return true;    
        }
    };
    mCustomView.setOnTouchListener(touchListener);
}


@Override
public boolean onCreateOptionsMenu(Menu menu) {
    // Inflate the menu; this adds items to the action bar if it is present.
    getMenuInflater().inflate(R.menu.main, menu);
    return true;
}

public boolean onOptionsItemSelected(MenuItem item){
    switch (item.getItemId()) {
      case R.id.black:
          Toast.makeText(this, "You have chosen " + getResources().getString(R.string.black) + ".",
                        Toast.LENGTH_SHORT).show();
          paint.setColor(Color.BLACK);
          color = Color.BLACK;         
          break;
      case R.id.red:
          Toast.makeText(this, "You have chosen " + getResources().getString(R.string.red) + ".",
                        Toast.LENGTH_SHORT).show();
          paint.setColor(Color.RED); 
          color = Color.RED;
          break;
      case R.id.blue:
          Toast.makeText(this, "You have chosen " + getResources().getString(R.string.blue) + ".",
                        Toast.LENGTH_SHORT).show();
          paint.setColor(Color.BLUE); 
          color = Color.BLUE;
          break;
      case R.id.yellow:
          Toast.makeText(this, "You have chosen " + getResources().getString(R.string.yellow) + ".",
                        Toast.LENGTH_SHORT).show();
          paint.setColor(Color.YELLOW); 
          color = Color.YELLOW;
          break;
      case R.id.erase:
          Toast.makeText(this, "You have chosen to clear the screen. The current pen is now Black.", Toast.LENGTH_SHORT).show();
          paint.setColor(Color.BLACK);
          color = Color.BLACK;
          path.reset();
          mCustomView.invalidate();
          item.setChecked(false);
          break;
      case R.id.next:
          nextScreen(); //saves the bitmap, and call startActivity(), crashing now
          return true;
      default:
          return super.onOptionsItemSelected(item);
      }
      item.setChecked(true);
      return true;
}

public void nextScreen(){
    try {
        FileOutputStream out = openFileOutput(files[0], Context.MODE_PRIVATE);
        pic.compress(Bitmap.CompressFormat.PNG, 100, out);
        out.close();
    } catch (Exception e){
        Toast.makeText(this, e.getMessage(), Toast.LENGTH_SHORT).show();
        return;
    }
    Intent i = new Intent(this.getApplicationContext(), SecondActivity.class);
    i.putExtra("filename.png", files);
    startActivity(i);
}

public class CustomView extends View {

    public CustomView(Context context) {
        super(context);
        paint.setAntiAlias(true);
        paint.setColor(color);
        paint.setStyle(Paint.Style.STROKE);
    }

    @Override
    protected void onDraw(Canvas canvas) {
        if (pic == null){
            pic = Bitmap.createBitmap(getMeasuredWidth(), getMeasuredHeight(), Bitmap.Config.ARGB_8888); //is this correct?
        }
        canvas.drawPath(path, paint);
        canvas.drawBitmap(pic, 0, 0, paint); //is this correct?
    }
}

}

4

1 回答 1

0

如果你想保存视图,你应该使用public Bitmap getDrawingCache (),见参考。尝试修改您的代码:

@Override
    protected void onDraw(Canvas canvas) {
        if (pic == null){
            pic = Bitmap.createBitmap(getMeasuredWidth(), getMeasuredHeight(), Bitmap.Config.ARGB_8888); //is this correct?
        }
        canvas.drawPath(path, paint);
        //canvas.drawBitmap(pic, 0, 0, paint); //is this correct?
    }

public void nextScreen(){
    try {
        Bitmap bitmap = mCustomView.getDrawingCache ();
        FileOutputStream out = openFileOutput(files[0], Context.MODE_PRIVATE);
        bitmap.compress(Bitmap.CompressFormat.PNG, 100, out);
        out.close();
    } catch (Exception e){
        Toast.makeText(this, e.getMessage(), Toast.LENGTH_SHORT).show();
        return;
    }
    Intent i = new Intent(this.getApplicationContext(), SecondActivity.class);
    i.putExtra("filename.png", files);
    startActivity(i);
}
于 2013-09-29T02:28:10.543 回答