现在,我正在使用 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?
}
}
}