我有一个 Canvas ,可以让用户绘制并允许他们保存然后共享。我遇到的问题是,一旦按下保存按钮,它就会被共享按钮取代。现在,如果用户不按共享,而是在现有图片上绘制新内容,我如何检查是否存在新路径,以便删除共享按钮并再次显示保存按钮?
XML:
<FrameLayout
android:id="@+id/viewd"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="3"
android:orientation="vertical"
android:layout_gravity="center" >
<LinearLayout
android:orientation="horizontal"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:padding="0dp"
android:background="@drawable/bd"
android:id="@+id/llFreeDraw" >
</LinearLayout>
</FrameLayout>
我的绘图 Java 类:
package com.test.testing;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.Paint.Style;
import android.view.MotionEvent;
import android.view.View;
import android.widget.TextView;
public class CustomView extends View {
Paint paint;
Path path;
float x = 0;
float y = 0;
private int cWhite = Color.WHITE;
public CustomView(Context context) {
super(context);
paint = new Paint();
path= new Path();
paint.setAlpha(255);
paint.setColor(cWhite);
paint.setStyle(Style.STROKE);
paint.setStrokeWidth(20);
}
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
canvas.drawPath(path,paint);
canvas.drawCircle(x, y, 10, paint);
}
public boolean onTouchEvent(MotionEvent event) {
int action = event.getAction();
switch (action) {
case MotionEvent.ACTION_DOWN:
path.moveTo(event.getX(), event.getY());
path.lineTo(event.getX(), event.getY());
invalidate();
break;
case MotionEvent.ACTION_MOVE:
x = event.getX();
y = event.getY();
path.lineTo(x, y);
invalidate();
break;
case MotionEvent.ACTION_UP:
path.lineTo(event.getX(), event.getY());
invalidate();
break;
case MotionEvent.ACTION_CANCEL:
break;
default:
break;
}
return true;
}
}
我的 MainActivity 类:
layout = (FrameLayout)findViewById(R.id.viewd);
//layout.removeAllViews();
view = new CustomView(FreeDraw.this);
view.setLayoutParams(new FrameLayout.LayoutParams(LayoutParams.MATCH_PARENT,LayoutParams.MATCH_PARENT));
layout.addView(view);
...
View.OnClickListener saveHandle = new View.OnClickListener() {
public void onClick(View v) {
new SaveImageTask().execute(null, null, null);
}
};
public class SaveImageTask extends AsyncTask<Void, Void, Void> {
@Override
protected Void doInBackground(Void... params) { //Running in background
View content = layout;
content.setDrawingCacheEnabled(true);
content.setDrawingCacheQuality(View.DRAWING_CACHE_QUALITY_HIGH);
Bitmap bitmap = content.getDrawingCache();
File folder = new File(Environment.getExternalStorageDirectory() + "/PB");
if (!folder.exists()) {
folder.mkdir();
}
file = new File(folder + "/pb_image_" + Math.random() + ".png");
FileOutputStream ostream;
try {
file.createNewFile();
ostream = new FileOutputStream(file);
bitmap.compress(CompressFormat.PNG, 100, ostream);
ostream.flush();
ostream.close();
isSaved = true;
} catch (Exception e) {
e.printStackTrace();
isSaved = false;
}
return null;
}
@Override
protected void onPreExecute() { //Activity is on progress
//displayToast("Your image is saving...");
btnSave.setVisibility(View.GONE);
btnShare.setVisibility(View.GONE);
pb.setVisibility(View.VISIBLE);
}
@Override
protected void onPostExecute(Void v) { //Activity is done...
if (isSaved == true) {
displayToast("Image was saved.");
btnSave.setVisibility(View.GONE);
btnShare.setVisibility(View.VISIBLE);
pb.setVisibility(View.GONE);
}
if (isSaved == false) {
displayToast("Unable to save image. Try again later.");
btnSave.setVisibility(View.VISIBLE);
btnShare.setVisibility(View.GONE);
pb.setVisibility(View.GONE);
}
}
}
如果绘制了新路径,如何显示“保存”按钮?
用图像画出我想做的事情......
我尝试将 Paint 类更改为:
package com.test.testing;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.Paint.Style;
import android.view.MotionEvent;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
public class CustomView extends View {
Paint paint;
Path path;
float x = 0;
float y = 0;
private int cWhite = Color.WHITE;
private Button btnS, btnSa;
public CustomView(Context context) {
super(context);
paint = new Paint();
path= new Path();
paint.setAlpha(255);
paint.setColor(cWhite);
paint.setStyle(Style.STROKE);
paint.setStrokeWidth(20);
btnS = (Button) findViewById(R.id.shareButton);
btnSa = (Button) findViewById(R.id.saveButton);
}
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
canvas.drawPath(path,paint);
canvas.drawCircle(x, y, 10, paint);
}
public boolean onTouchEvent(MotionEvent event) {
int action = event.getAction();
switch (action) {
case MotionEvent.ACTION_DOWN:
path.moveTo(event.getX(), event.getY());
path.lineTo(event.getX(), event.getY());
if (btnS.getVisibility() == View.VISIBLE && btnS != null) {
btnS.setVisibility(View.GONE);
btnSa.setVisibility(View.VISIBLE);
}
else {
//do nothing...
}
invalidate();
break;
case MotionEvent.ACTION_MOVE:
x = event.getX();
y = event.getY();
path.lineTo(x, y);
invalidate();
break;
case MotionEvent.ACTION_UP:
path.lineTo(event.getX(), event.getY());
invalidate();
break;
case MotionEvent.ACTION_CANCEL:
break;
default:
break;
}
return true;
}
}
在我的 ACTION_DOWN
事件中添加了以下行,以隐藏“共享”按钮并显示“保存”按钮:
if (btnS.getVisibility() == View.VISIBLE && btnS != null) {
btnS.setVisibility(View.GONE);
btnSa.setVisibility(View.VISIBLE);
}
else {
//do nothing...
}
但是我收到一个错误,我的 LogCat:
09-04 21:35:58.752: E/AndroidRuntime(3835): FATAL EXCEPTION: main
09-04 21:35:58.752: E/AndroidRuntime(3835): java.lang.NullPointerException
09-04 21:35:58.752: E/AndroidRuntime(3835): at com.test.testing.CustomView.onTouchEvent(CustomView.java:47)
09-04 21:35:58.752: E/AndroidRuntime(3835): at android.view.View.dispatchTouchEvent(View.java:7246)
09-04 21:35:58.752: E/AndroidRuntime(3835): at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2174)
09-04 21:35:58.752: E/AndroidRuntime(3835): at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1875)
09-04 21:35:58.752: E/AndroidRuntime(3835): at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2174)
09-04 21:35:58.752: E/AndroidRuntime(3835): at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1875)
09-04 21:35:58.752: E/AndroidRuntime(3835): at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2174)
09-04 21:35:58.752: E/AndroidRuntime(3835): at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1875)
09-04 21:35:58.752: E/AndroidRuntime(3835): at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2174)
09-04 21:35:58.752: E/AndroidRuntime(3835): at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1875)
09-04 21:35:58.752: E/AndroidRuntime(3835): at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2174)
09-04 21:35:58.752: E/AndroidRuntime(3835): at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1875)
09-04 21:35:58.752: E/AndroidRuntime(3835): at com.android.internal.policy.impl.PhoneWindow$DecorView.superDispatchTouchEvent(PhoneWindow.java:1953)
09-04 21:35:58.752: E/AndroidRuntime(3835): at com.android.internal.policy.impl.PhoneWindow.superDispatchTouchEvent(PhoneWindow.java:1405)
09-04 21:35:58.752: E/AndroidRuntime(3835): at android.app.Activity.dispatchTouchEvent(Activity.java:2410)
09-04 21:35:58.752: E/AndroidRuntime(3835): at com.android.internal.policy.impl.PhoneWindow$DecorView.dispatchTouchEvent(PhoneWindow.java:1901)
09-04 21:35:58.752: E/AndroidRuntime(3835): at android.view.View.dispatchPointerEvent(View.java:7426)
09-04 21:35:58.752: E/AndroidRuntime(3835): at android.view.ViewRootImpl.deliverPointerEvent(ViewRootImpl.java:3220)
09-04 21:35:58.752: E/AndroidRuntime(3835): at android.view.ViewRootImpl.deliverInputEvent(ViewRootImpl.java:3165)
09-04 21:35:58.752: E/AndroidRuntime(3835): at android.view.ViewRootImpl.doProcessInputEvents(ViewRootImpl.java:4292)
09-04 21:35:58.752: E/AndroidRuntime(3835): at android.view.ViewRootImpl.enqueueInputEvent(ViewRootImpl.java:4271)
09-04 21:35:58.752: E/AndroidRuntime(3835): at android.view.ViewRootImpl$WindowInputEventReceiver.onInputEvent(ViewRootImpl.java:4363)
09-04 21:35:58.752: E/AndroidRuntime(3835): at android.view.InputEventReceiver.dispatchInputEvent(InputEventReceiver.java:179)
09-04 21:35:58.752: E/AndroidRuntime(3835): at android.os.MessageQueue.nativePollOnce(Native Method)
09-04 21:35:58.752: E/AndroidRuntime(3835): at android.os.MessageQueue.next(MessageQueue.java:125)
09-04 21:35:58.752: E/AndroidRuntime(3835): at android.os.Looper.loop(Looper.java:124)
09-04 21:35:58.752: E/AndroidRuntime(3835): at android.app.ActivityThread.main(ActivityThread.java:5195)
09-04 21:35:58.752: E/AndroidRuntime(3835): at java.lang.reflect.Method.invokeNative(Native Method)
09-04 21:35:58.752: E/AndroidRuntime(3835): at java.lang.reflect.Method.invoke(Method.java:511)
09-04 21:35:58.752: E/AndroidRuntime(3835): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:795)
09-04 21:35:58.752: E/AndroidRuntime(3835): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:562)
09-04 21:35:58.752: E/AndroidRuntime(3835): at dalvik.system.NativeStart.main(Native Method)
有什么建议如何修复它或如何完成该步骤吗?
最佳答案
您会收到 NullPointerException
,因为在 onTouchEvent()
方法中按钮引用为 null
。发生这种情况是因为您直接使用 findViewById()
查找按钮,该按钮仅在自定义 View 及其 subview 中查找按钮。所以,而不是:
btnS = (Button) findViewById(R.id.shareButton);
btnSa = (Button) findViewById(R.id.saveButton);
在包含按钮和自定义 View 的 Activity
(构造函数中传递的 Context
参数)中查找按钮:
btnS = (Button)((Activity) context).findViewById(R.id.shareButton);
btnSa = (Button)((Activity) context).findViewById(R.id.saveButton);.
关于java - 使按钮在 Canvas 上绘制的新路径上可见,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18626487/