I am working on a drawing app and following the online tutorial here: http://mobile.tutsplus.com/tutorials/android/android-sdk-create-a-drawing-app-essential-functionality/
There are no problem until the last part (as above). Then, I have tried to Clean and import the project again (virtual device was restarted everytime), but the problem still exists.
Would you mind help me to take a look at this?
Thanks in advance!!
PS I am using Eclipse ADT
Here is the error log:
09-01 03:27:25.144: E/AndroidRuntime(788): FATAL EXCEPTION: main
09-01 03:27:25.144: E/AndroidRuntime(788): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.earth0102.luckydraw/com.earth0102.luckydraw.MainActivity}: java.lang.ClassCastException: com.earth0102.luckydraw.MainActivity cannot be cast to android.view.View$OnClickListener
09-01 03:27:25.144: E/AndroidRuntime(788): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2180)
09-01 03:27:25.144: E/AndroidRuntime(788): at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2230)
09-01 03:27:25.144: E/AndroidRuntime(788): at android.app.ActivityThread.access$600(ActivityThread.java:141)
09-01 03:27:25.144: E/AndroidRuntime(788): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1234)
09-01 03:27:25.144: E/AndroidRuntime(788): at android.os.Handler.dispatchMessage(Handler.java:99)
09-01 03:27:25.144: E/AndroidRuntime(788): at android.os.Looper.loop(Looper.java:137)
09-01 03:27:25.144: E/AndroidRuntime(788): at android.app.ActivityThread.main(ActivityThread.java:5041)
09-01 03:27:25.144: E/AndroidRuntime(788): at java.lang.reflect.Method.invokeNative(Native Method)
09-01 03:27:25.144: E/AndroidRuntime(788): at java.lang.reflect.Method.invoke(Method.java:511)
09-01 03:27:25.144: E/AndroidRuntime(788): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:793)
09-01 03:27:25.144: E/AndroidRuntime(788): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:560)
09-01 03:27:25.144: E/AndroidRuntime(788): at dalvik.system.NativeStart.main(Native Method)
09-01 03:27:25.144: E/AndroidRuntime(788): Caused by: java.lang.ClassCastException: com.earth0102.luckydraw.MainActivity cannot be cast to android.view.View$OnClickListener
09-01 03:27:25.144: E/AndroidRuntime(788): at com.earth0102.luckydraw.MainActivity.onCreate(MainActivity.java:56)
09-01 03:27:25.144: E/AndroidRuntime(788): at android.app.Activity.performCreate(Activity.java:5104)
09-01 03:27:25.144: E/AndroidRuntime(788): at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1080)
09-01 03:27:25.144: E/AndroidRuntime(788): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2144)
09-01 03:27:25.144: E/AndroidRuntime(788): ... 11 more
AndroidManifest.xml :
<uses-sdk android:minSdkVersion="14" android:targetSdkVersion="17" /> <application android:allowBackup="true" android:icon="@drawable/ic_launcher" android:label="@string/app_name" android:theme="@style/CustomTheme" > <activity android:name="com.earth0102.luckydraw.MainActivity" android:label="@string/app_name" android:screenOrientation="portrait"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> </application>
MainActivity.java
package com.earth0102.luckydraw;
import android.os.Bundle;
import android.app.Activity;
import android.app.Dialog;
import android.view.Menu;
//implement the ability for the user to choose colors
import android.view.View;
import android.widget.ImageButton;
import android.widget.LinearLayout;
//other features
import java.util.UUID;
import android.provider.MediaStore;
import android.app.AlertDialog;
import android.app.AlertDialog.Builder;
import android.content.DialogInterface;
import android.view.View.OnClickListener;
import android.widget.Toast;
public class MainActivity extends Activity implements onClickListener
{
//let user to choose colors from the palette
private DrawingView drawView;
//variable to represent the paint color button in the palette
private ImageButton currPaint, drawBtn, eraseBtn, newBtn, saveBtn;
//variable in three dimension
private float smallBrush,mediumBrush,largeBrush;
@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
drawView=(DrawingView)findViewById(R.id.drawing);
//1. retrieve the first paint color button in the palette area, which is initially going to be selected.
LinearLayout paintLayout = (LinearLayout) findViewById(R.id.paint_colors);
//2. get the first button and store it as the instance variable.
currPaint = (ImageButton) paintLayout.getChildAt(0);
//3. we use a different drawable image on the button to show that it is currently selected:
currPaint.setImageDrawable(getResources().getDrawable(R.drawable.paint_pressed));
smallBrush=getResources().getInteger(R.integer.small_size);
mediumBrush=getResources().getInteger(R.integer.medium_size);
largeBrush=getResources().getInteger(R.integer.large_size);
//draw button
drawBtn = (ImageButton)findViewById(R.id.draw_btn);
drawBtn.setOnClickListener((OnClickListener)this);
//erase button
eraseBtn = (ImageButton)findViewById(R.id.erase_btn);
eraseBtn.setOnClickListener((OnClickListener)this);
//new painting
newBtn = (ImageButton)findViewById(R.id.new_btn);
newBtn.setOnClickListener((OnClickListener)this);
//new painting
saveBtn = (ImageButton)findViewById(R.id.save_btn);
saveBtn.setOnClickListener((OnClickListener)this);
}
@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 void paintClicked(View view)
{
drawView.setBrushSize(drawView.getLastBrushSize());
//use chosen color
//1. check that the user has clicked a paint color
if(view!=currPaint)
{
//update color
ImageButton imgView = (ImageButton)view;
String color = view.getTag().toString();
drawView.setColor(color);
//update the UI to reflect the new chosen paint and set the previous one back to normal
imgView.setImageDrawable(getResources().getDrawable(R.drawable.paint_pressed));
currPaint.setImageDrawable(getResources().getDrawable(R.drawable.paint));
currPaint=(ImageButton)view;
}
}
@Override
public void onClick(View view) {
// TODO Auto-generated method stub
if(view.getId()==R.id.draw_btn)
{
//draw button clicked
final Dialog brushDialog = new Dialog(this);
brushDialog.setTitle("Brush size");
brushDialog.setContentView(R.layout.brush_chooser);
//listen for clicks on size buttons - small, medium, large
ImageButton smallBtn = (ImageButton)brushDialog.findViewById(R.id.small_brush);
smallBtn.setOnClickListener(new OnClickListener()
{
@Override
public void onClick(View v)
{
drawView.setBrushSize(smallBrush);
drawView.setLastBrushSize(smallBrush);
brushDialog.dismiss();
}
});
ImageButton mediumBtn = (ImageButton)brushDialog.findViewById(R.id.medium_brush);
mediumBtn.setOnClickListener(new OnClickListener()
{
@Override
public void onClick(View v)
{
drawView.setBrushSize(mediumBrush);
drawView.setLastBrushSize(mediumBrush);
brushDialog.dismiss();
}
});
ImageButton largeBtn = (ImageButton)brushDialog.findViewById(R.id.large_brush);
largeBtn.setOnClickListener(new OnClickListener()
{
@Override
public void onClick(View v)
{
drawView.setBrushSize(largeBrush);
drawView.setLastBrushSize(largeBrush);
brushDialog.dismiss();
}
});
brushDialog.show();
}//end of draw button
else if (view.getId()==R.id.erase_btn)
{
//switch to erase - choose size
final Dialog brushDialog = new Dialog(this);
brushDialog.setTitle("Eraser size:");
brushDialog.setContentView(R.layout.brush_chooser);
//cancel - listen for clicks on size buttons
ImageButton smallBtn = (ImageButton)brushDialog.findViewById(R.id.small_brush);
smallBtn.setOnClickListener(new OnClickListener()
{
@Override
public void onClick(View v)
{
drawView.setBrushSize(smallBrush);
drawView.setLastBrushSize(smallBrush);
drawView.setErase(false);
brushDialog.dismiss();
}
});
ImageButton mediumBtn = (ImageButton)brushDialog.findViewById(R.id.medium_brush);
mediumBtn.setOnClickListener(new OnClickListener()
{
@Override
public void onClick(View v)
{
drawView.setBrushSize(mediumBrush);
drawView.setLastBrushSize(mediumBrush);
drawView.setErase(false);
brushDialog.dismiss();
}
});
//listen for clicks on size buttons
ImageButton largeBtn = (ImageButton)brushDialog.findViewById(R.id.large_brush);
largeBtn.setOnClickListener(new OnClickListener()
{
@Override
public void onClick(View v)
{
drawView.setBrushSize(largeBrush);
drawView.setLastBrushSize(largeBrush);
drawView.setErase(false);
brushDialog.dismiss();
}
});
brushDialog.show();
}//end of erase button
else if (view.getId()==R.id.new_btn)
{
String cancel = "Cancel";
//new button
AlertDialog.Builder newDialog = new AlertDialog.Builder(this);
newDialog.setTitle("New drawing");
newDialog.setMessage("Start new drawing (you will lose the current drawing)?");
newDialog.setPositiveButton("Yes",new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
// TODO Auto-generated method stub
drawView.startNew();
dialog.dismiss();
}
});
newDialog.setNegativeButton("Cancel", new DialogInterface.OnClickListener(){
public void onClick(DialogInterface dialog, int which){
dialog.cancel();
}
});
newDialog.show();
}//end of new button
else if (view.getId()==R.id.save_btn)
{
AlertDialog.Builder saveDialog = new AlertDialog.Builder(this);
saveDialog.setTitle("Save drawing");
saveDialog.setMessage("Save drawing to device Gallery?");
saveDialog.setPositiveButton("Yes", new DialogInterface.OnClickListener(){
public void onClick(DialogInterface dialog, int which)
{
//save drawing-use insertImage to attempt to write the image to the media store
//for images on the device, which should save it to the user gallery.
//We pass the content resolver, drawing cache for the displayed View, a randomly generated
//UUID string for the filename with JPG extension and a short description.
drawView.setDrawingCacheEnabled(true);
String imgSaved=MediaStore.Images.Media.insertImage(
getContentResolver(),drawView.getDrawingCache(),
UUID.randomUUID().toString()+".jpg","drawing");
if(imgSaved!=null)
{
Toast savedToast = Toast.makeText(getApplicationContext(),
"Drawing saved to Gallery!", Toast.LENGTH_SHORT);
savedToast.show();
}
else
{
Toast unsavedToast = Toast.makeText(getApplicationContext(), "Oops! Image could not be saved.",
Toast.LENGTH_SHORT);
unsavedToast.show();
}
drawView.destroyDrawingCache();
}
});
saveDialog.setNegativeButton("Cancel", new DialogInterface.OnClickListener(){
public void onClick(DialogInterface dialog, int which){
dialog.cancel();
}
});
saveDialog.show();
}//end of save button
}//onClick method
}
DrawingView.java
package com.earth0102.luckydraw;
import android.content.Context;
import android.view.View;
import android.util.AttributeSet;
//for drawing
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Path;
import android.view.MotionEvent;
//other features
import android.graphics.PorterDuff;
import android.graphics.PorterDuffXfermode;
import android.util.TypedValue;
public class DrawingView extends View
{
private float brushSize, lastBrushSize;
//eraser flag
private boolean erase=false;
//drawing path
private Path drawPath;
//drawing and canvas paint
private Paint drawPaint, canvasPaint;
//initial color
private int paintColor = 0xFF000000;
//canvas
private Canvas drawCanvas;
//canvas bitmap
private Bitmap canvasBitmap;
public DrawingView(Context context, AttributeSet attrs)
{
super(context, attrs);
setupDrawing();
}
private void setupDrawing()
{
//get drawing area setup for interaction
brushSize=getResources().getInteger(R.integer.medium_size);
lastBrushSize=brushSize;
//initial objects
drawPath=new Path();
drawPaint =new Paint();
drawPaint.setColor(paintColor);
drawPaint.setAntiAlias(true);
drawPaint.setStrokeWidth(brushSize);
drawPaint.setStyle(Paint.Style.STROKE);
drawPaint.setStrokeJoin(Paint.Join.ROUND);
drawPaint.setStrokeCap(Paint.Cap.ROUND);
//instantiating a canvas paint object
canvasPaint = new Paint(Paint.DITHER_FLAG);
}
public void setBrushSize(float newSize)
{
//update size for each brush
float pixelAmount = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,
newSize, getResources().getDisplayMetrics());
brushSize=pixelAmount;
drawPaint.setStrokeWidth(brushSize);
}
public void setLastBrushSize(float lastSize)
{
lastBrushSize=lastSize;
}
public float getLastBrushSize()
{
return lastBrushSize;
}
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh)
{
// override a couple of methods to make
//the custom View function as a drawing View
//view given size
super.onSizeChanged(w,h,oldw,oldh);
canvasBitmap = Bitmap.createBitmap(w,h,Bitmap.Config.ARGB_8888);
drawCanvas = new Canvas(canvasBitmap);
}
@Override
protected void onDraw(Canvas canvas)
{
//To allow the class to function as a custom drawing View,
//we also need to override the onDraw method
//draw view
canvas.drawBitmap(canvasBitmap, 0,0, canvasPaint);
canvas.drawPath(drawPath, drawPaint);
}
@Override
public boolean onTouchEvent(MotionEvent event)
{
//detect user touch
float touchX=event.getX();
float touchY=event.getY();
switch (event.getAction())
{
case MotionEvent.ACTION_DOWN:
drawPath.moveTo(touchX, touchY);
break;
case MotionEvent.ACTION_MOVE:
drawPath.lineTo(touchX, touchY);
break;
case MotionEvent.ACTION_UP:
drawPath.lineTo(touchX, touchY);
drawCanvas.drawPath(drawPath, drawPaint);
drawPath.reset();
break;
default:
return false;
}
//redraw - Calling invalidate will cause the onDraw method to execute.
invalidate();
return true;
}
public void setColor(String newColor)
{
//set color and start by invalidating the view
invalidate();
//parse and set the color for drawing
paintColor = Color.parseColor(newColor);
drawPaint.setColor(paintColor);
}
public void setErase (Boolean isErase)
{
//set erase true or false
erase=isErase;
if(erase)
drawPaint.setXfermode(new PorterDuffXfermode (PorterDuff.Mode.CLEAR));
else
drawPaint.setXfermode(null);
}
public void startNew()
{
//set a new draw
drawCanvas.drawColor(0,PorterDuff.Mode.CLEAR);
invalidate();
}
}
OnClickListener.java - it's requested to add another class to implement onClickListener in MainActivity, and so on.
package com.earth0102.luckydraw;
import android.view.View;
public interface onClickListener
{
public void onClick(View view);
}
In the MainActivity
onCreate
function, you are doing:
drawBtn.setOnClickListener((OnClickListener)this);
Here you are casing this
to OnClickListener
which is giving error. this
gives you the activity context
. You can trying to cast the activity context to OnClickListener
, which is creating the casting exception. You can try just passing in the Activity's context like:
drawBtn.setOnClickListener(this);
Do the same for all the other buttons and don't cast it to OnClickListener
. See if this changes something.
In MainActivity, you should implement View.OnClickListener . in this case, you don't need your own interface OnClickListener.java, just use View.OnClickListener
I mean, change
public class MainActivity extends Activity implements onClickListener
to
public class MainActivity extends Activity implements View.OnClickListener
You are casting your activity to on click listener.Do like this:
Button.setonclicklistener(commonclicklistener);
Onclicklistener commonclicklistener = new view.onclicklistener{
//add a switch case based on your buttons and perform the code here like
Switch(v.getid)
Case (draw button):
//code
Case(imagebuttpn):
//code
}
This is an rough idea .you can find code in net.I am typing through mobile otherwise would have provided with the code.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.