2012-02-27 15 views
0

キャンバスにビットマップを描画する機能を実装していて、全体をキャンバス領域にドラッグアンドドロップできるという問題があります。ドラッグアンドドロップAPIデモのサンプルコードは正常に動作していますが、コード内に同じ機能を実装すると、ArrrayOutOfBoundsExceptionが返されます。何度かうまく動作していることを意味し、キャンバスに触れた後にエラーを返すことがあります。ソースにバグが見つかった場合は、問題の解決策を提案してください。ArryOutOfBoundsExceptionキャンバス上のビットマップをドラッグ&ドロップするとき

エラー・スタック:

02-27 11:41:16.046: E/AndroidRuntime(5413): FATAL EXCEPTION: main 
02-27 11:41:16.046: E/AndroidRuntime(5413): java.lang.ArrayIndexOutOfBoundsException 
02-27 11:41:16.046: E/AndroidRuntime(5413):  at com.TestFace.FaceDetect.DrawView.onTouchEvent(DrawView.java:132) 
02-27 11:41:16.046: E/AndroidRuntime(5413):  at android.view.View.dispatchTouchEvent(View.java:3766) 
02-27 11:41:16.046: E/AndroidRuntime(5413):  at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:936) 
02-27 11:41:16.046: E/AndroidRuntime(5413):  at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:936) 
02-27 11:41:16.046: E/AndroidRuntime(5413):  at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:936) 
02-27 11:41:16.046: E/AndroidRuntime(5413):  at com.android.internal.policy.impl.PhoneWindow$DecorView.superDispatchTouchEvent(PhoneWindow.java:1676) 
02-27 11:41:16.046: E/AndroidRuntime(5413):  at com.android.internal.policy.impl.PhoneWindow.superDispatchTouchEvent(PhoneWindow.java:1112) 
02-27 11:41:16.046: E/AndroidRuntime(5413):  at android.app.Activity.dispatchTouchEvent(Activity.java:2086) 
02-27 11:41:16.046: E/AndroidRuntime(5413):  at com.android.internal.policy.impl.PhoneWindow$DecorView.dispatchTouchEvent(PhoneWindow.java:1660) 
02-27 11:41:16.046: E/AndroidRuntime(5413):  at android.view.ViewRoot.handleMessage(ViewRoot.java:1785) 
02-27 11:41:16.046: E/AndroidRuntime(5413):  at android.os.Handler.dispatchMessage(Handler.java:99) 
02-27 11:41:16.046: E/AndroidRuntime(5413):  at android.os.Looper.loop(Looper.java:123) 
02-27 11:41:16.046: E/AndroidRuntime(5413):  at android.app.ActivityThread.main(ActivityThread.java:4627) 
02-27 11:41:16.046: E/AndroidRuntime(5413):  at java.lang.reflect.Method.invokeNative(Native Method) 
02-27 11:41:16.046: E/AndroidRuntime(5413):  at java.lang.reflect.Method.invoke(Method.java:521) 
02-27 11:41:16.046: E/AndroidRuntime(5413):  at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:860) 
02-27 11:41:16.046: E/AndroidRuntime(5413):  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:618) 
02-27 11:41:16.046: E/AndroidRuntime(5413):  at dalvik.system.NativeStart.main(Native Method) 

DrawView.java:

パッケージcom.TestFace.FaceDetect。

import java.io.IOException; 
import java.net.MalformedURLException; 

import android.content.Context; 
import android.graphics.Bitmap; 
import android.graphics.BitmapFactory; 
import android.graphics.Canvas; 
import android.graphics.Point; 
import android.graphics.drawable.BitmapDrawable; 
import android.graphics.drawable.Drawable; 
import android.view.MotionEvent; 
import android.view.View; 

import com.TestFace.FaceDetect.Util.ResultPack; 

public class DrawView extends View { 
    private ColorBall[] colorballs = new ColorBall[3]; // array that holds the balls 
    private int balID = 0; // variable to know what ball is being dragged 
    ResultPack result = ResultPack.getSingletonObject(); 
    Bitmap myBitmap,myBitmap_Circle; 
    int width, height; 
    public DrawView(Context context) { 
     super(context); 
     setFocusable(true); //necessary for getting the touch events 

     // setting the start point for the balls 
     Point point1 = new Point(); 
     point1.x = (int)result.getEyeLeftX()+50; 
     point1.y = (int)result.getEyeLeftY()+25; 
     Point point2 = new Point(); 
     point2.x = (int)result.getEyeRightX()+50; 
     point2.y = (int)result.getEyeRightY()+25; 
     Point point3 = new Point(); 
     point3.x = (int)result.getMouthCenterX()+50; 
     point3.y = (int)result.getMouthCenterY()+25; 

     Drawable d=null; 
     try { 
      d = drawable_from_url(result.getImgUrl(), "Image Url"); 
     } catch (MalformedURLException e) { 
      // TODO Auto-generated catch block 
      e.printStackTrace(); 
     } catch (IOException e) { 
      // TODO Auto-generated catch block 
      e.printStackTrace(); 
     } 

     myBitmap=((BitmapDrawable)d).getBitmap(); 
     myBitmap_Circle = BitmapFactory.decodeResource(getResources(), R.drawable.circle1); 
     // declare each ball with the ColorBall class 
     colorballs[0] = new ColorBall(context,myBitmap_Circle, point1); 
     colorballs[1] = new ColorBall(context,myBitmap_Circle, point2); 
     colorballs[2] = new ColorBall(context,myBitmap_Circle, point3); 
     width=myBitmap.getWidth(); 
     height=myBitmap.getHeight(); 


    } 

    Drawable drawable_from_url(String url, String src_name) throws java.net.MalformedURLException, java.io.IOException 
    { 
     return Drawable.createFromStream(((java.io.InputStream)new java.net.URL(url).getContent()), src_name); 
    } 

    // the method that draws the balls 
    @Override protected void onDraw(Canvas canvas) { 
     //canvas.drawColor(0xFFCCCCCC);  //if you want another background color  
     canvas.drawBitmap(myBitmap, 0,0, null); 
     //draw the balls on the canvas 
     for (ColorBall ball : colorballs) { 
      canvas.drawBitmap(ball.getBitmap(), ball.getX(), ball.getY(), null); 
      } 
    } 

    // events when touching the screen 
    public boolean onTouchEvent(MotionEvent event) { 
     int eventaction = event.getAction(); 

     int X = (int)event.getX(); 
     int Y = (int)event.getY(); 

     switch (eventaction) { 

     case MotionEvent.ACTION_DOWN: // touch down so check if the finger is on a ball 
      balID = 0; 
      for (int i=0;i<colorballs.length;i++) { 
       // check if inside the bounds of the ball (circle) 
       // get the center for the ball 
       int centerX = colorballs[i].getX() + 25; 
       int centerY = colorballs[i].getY() + 25; 

       // calculate the radius from the touch to the center of the ball 
       double radCircle = Math.sqrt((double) (((centerX-X)*(centerX-X)) + (centerY-Y)*(centerY-Y))); 
       System.out.println("The Rad Circle:"+radCircle); 
       // if the radius is smaller then 23 (radius of a ball is 22), then it must be on the ball 
       if (radCircle < 23){ 

        balID = colorballs[i].getID(); 

       } 

       // check all the bounds of the ball (square) 
       //if (X > ball.getX() && X < ball.getX()+50 && Y > ball.getY() && Y < ball.getY()+50){ 
       // balID = ball.getID(); 
       // break; 
       //} 
       } 

      break; 


     case MotionEvent.ACTION_MOVE: // touch drag with the ball 
      // move the balls the same as the finger 
      if (balID > 0) { 
       colorballs[balID-1].setX(X-25); 
       colorballs[balID-1].setY(Y-25); 
      } 

      break; 

     case MotionEvent.ACTION_UP: 
      // touch drop - just do things here after dropping 

      break; 
     } 
     // redraw the canvas 
     invalidate(); 
     return true; 

    } 
} 

ColorBall.java:

package com.TestFace.FaceDetect; 

import android.content.Context; 
import android.graphics.Bitmap; 
import android.graphics.BitmapFactory; 
import android.graphics.Point; 

public class ColorBall { 
private Bitmap img; // the image of the ball 
private int coordX = 0; // the x coordinate at the canvas 
private int coordY = 0; // the y coordinate at the canvas 
private int id; // gives every ball his own id, for now not necessary 
private static int count = 1; 
private boolean goRight = true; 
private boolean goDown = true; 

    public ColorBall(Context context, Bitmap drawable) { 

     BitmapFactory.Options opts = new BitmapFactory.Options(); 
     opts.inJustDecodeBounds = true; 
     //img = BitmapFactory.decodeResource(context.getResources(), drawable); 
     img = drawable; 
     id=count; 
     count++; 
    } 

    public ColorBall(Context context, Bitmap drawable, Point point) { 

     BitmapFactory.Options opts = new BitmapFactory.Options(); 
     opts.inJustDecodeBounds = true; 
     //img = BitmapFactory.decodeResource(context.getResources(), drawable); 
     img = drawable; 
     id=count; 
     count++; 
     coordX= point.x; 
     coordY = point.y; 

    } 

    public static int getCount() { 
     return count; 
    } 

    void setX(int newValue) { 
     coordX = newValue; 
    } 

    public int getX() { 
     return coordX; 
    } 

    void setY(int newValue) { 
     coordY = newValue; 
    } 

    public int getY() { 
     return coordY; 
    } 

    public int getID() { 
     return id; 
    } 

    public Bitmap getBitmap() { 
     return img; 
    } 

    public void moveBall(int goX, int goY) { 
     // check the borders, and set the direction if a border has reached 
     if (coordX > 270){ 
      goRight = false; 
     } 
     if (coordX < 0){ 
      goRight = true; 
     } 
     if (coordY > 400){ 
      goDown = false; 
     } 
     if (coordY < 0){ 
      goDown = true; 
     } 
     // move the x and y 
     if (goRight){ 
      coordX += goX; 
     }else 
     { 
      coordX -= goX; 
     } 
     if (goDown){ 
      coordY += goY; 
     }else 
     { 
      coordY -= goY; 
     } 

    } 

} 
+0

まず、132行目の 'DrawView'の行に印を付けます。私は、それは 'colorballs [balID-1] .setX(X-25); 'の行です。より明確にするには、 'log.i(" "、" balID = "+ balID);を加えて、この行の直前にある' balID'変数の値を出力してください; –

+0

はい、あなたは正しく、エラーは同じです私は3つのボールが3つのIDSしか持たないので、それは必要ではありません。 –

答えて

0

問題は、あなたのColorBallのIDを生成し、colorballs配列のインデックスとして、このIDを使用しようということである。

private static int count = 1; 
public ColorBall(Context context, Bitmap drawable) { 
    ... 
    id=count; 
    count++; 
} 

および:

protected void onDraw(Canvas canvas) { 
    ... 
    case MotionEvent.ACTION_MOVE: // touch drag with the ball 
     // move the balls the same as the finger 
     if (balID > 0) { 
      colorballs[balID-1].setX(X-25); 
      colorballs[balID-1].setY(Y-25); 
     } 
     break; 
    ... 
} 

明らかに間違っています。それはあなたがすることによってColorBallオブジェクトを参照したいColorBallIDであれば、そうでない場合を参照するために、配列内の要素のインデックスを使用し、すなわちHashMap<Integer, ColorBall>ColorBallオブジェクトのリストを保持するために、コレクションの他のタイプを使用することを検討してください特定のColorBallオブジェクトです。

関連する問題