RuntimeException:无法启动活动(无法将主活动转换为android.view.View .view $OnClickListener)

时间:2022-04-10 00:22:46

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/

我正在开发一个绘图应用程序,以下是在线教程:http://mobile.tutsplus.com/tutorials/android/android-sdk-create-a- drawing-app-essentialfunctionality/

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!!

你能帮我看看这个吗?提前谢谢! !

P.S. I am using Eclipse ADT

我正在使用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 :

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

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

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.

OnClickListener。java——它被请求添加另一个类来实现主活动中的onClickListener,等等。

package com.earth0102.luckydraw;

import android.view.View;

public interface onClickListener 
{
    public void onClick(View view);
}

3 个解决方案

#1


1  

In MainActivity, you should implement View.OnClickListener. in this case, you don't need your own interface OnClickListener.java, just use View.OnClickListener

在MainActivity中,应该实现View.OnClickListener。在这种情况下,不需要自己的OnClickListener接口。java,只使用View.OnClickListener

I mean, change

我的意思是,改变

public class MainActivity extends Activity implements onClickListener

public class MainActivity扩展了活动实现onClickListener

to

public class MainActivity extends Activity implements View.OnClickListener

public class MainActivity扩展了活动实现View.OnClickListener

#2


1  

In the MainActivity onCreate function, you are doing:

在MainActivity onCreate函数中,你在做:

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:

这里是OnClickListener,它会出错。这将为您提供活动上下文。您可以尝试将活动上下文强制转换为OnClickListener,后者正在创建强制转换异常。您可以尝试传入活动的上下文,比如:

drawBtn.setOnClickListener(this);

Do the same for all the other buttons and don't cast it to OnClickListener. See if this changes something.

对所有其他按钮执行相同的操作,不要将其强制转换为OnClickListener。看看这会不会改变什么。

#3


0  

You are casting your activity to on click listener.Do like this:

您正在将您的活动转换为on click listener。这样做:

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.

这是一个粗略的想法,你可以在网上找到代码。我正在通过手机打字,否则会提供代码。

#1


1  

In MainActivity, you should implement View.OnClickListener. in this case, you don't need your own interface OnClickListener.java, just use View.OnClickListener

在MainActivity中,应该实现View.OnClickListener。在这种情况下,不需要自己的OnClickListener接口。java,只使用View.OnClickListener

I mean, change

我的意思是,改变

public class MainActivity extends Activity implements onClickListener

public class MainActivity扩展了活动实现onClickListener

to

public class MainActivity extends Activity implements View.OnClickListener

public class MainActivity扩展了活动实现View.OnClickListener

#2


1  

In the MainActivity onCreate function, you are doing:

在MainActivity onCreate函数中,你在做:

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:

这里是OnClickListener,它会出错。这将为您提供活动上下文。您可以尝试将活动上下文强制转换为OnClickListener,后者正在创建强制转换异常。您可以尝试传入活动的上下文,比如:

drawBtn.setOnClickListener(this);

Do the same for all the other buttons and don't cast it to OnClickListener. See if this changes something.

对所有其他按钮执行相同的操作,不要将其强制转换为OnClickListener。看看这会不会改变什么。

#3


0  

You are casting your activity to on click listener.Do like this:

您正在将您的活动转换为on click listener。这样做:

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.

这是一个粗略的想法,你可以在网上找到代码。我正在通过手机打字,否则会提供代码。