RuntimeException:无法启动活动(MainActivity无法强制转换为android.view.View $ OnClickListener)

时间:2013-09-01 04:37:56

标签: java android eclipse casting main-activity

我正在制作一个绘图应用程序并按照在线教程进行操作: http://mobile.tutsplus.com/tutorials/android/android-sdk-create-a-drawing-app-essential-functionality/

直到最后一部分(如上所述)没有问题。然后,我尝试再次清理并导入项目(每次都重新启动虚拟设备),但问题仍然存在。

你介意帮我看一下吗? 在此先感谢!!

P.S。我正在使用Eclipse ADT

以下是错误日志:

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 - 要求添加另一个类以在MainActivity中实现onClickListener,依此类推。

package com.earth0102.luckydraw;

import android.view.View;

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

3 个答案:

答案 0 :(得分:1)

MainActivity onCreate函数中,您正在执行:

drawBtn.setOnClickListener((OnClickListener)this);

此处您将thisOnClickListener联系起来,这是错误的。 this为您提供了活动context。您可以尝试将活动上下文转换为OnClickListener,这将创建转换异常。您可以尝试传递Activity的上下文,如:

drawBtn.setOnClickListener(this);

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

答案 1 :(得分:1)

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

我的意思是,改变

  

公共类MainActivity扩展了Activity实现onClickListener

  

公共类MainActivity扩展Activity实现View.OnClickListener

答案 2 :(得分:0)

您正在将您的活动投射到点击侦听器。请执行以下操作:

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
}

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