2014-11-08 4 views
0

응용 프로그램이 새 버블을 만들려고 할 때 MSG 오류가 발생했습니다.오류 새 버블 생성시 MSG

프레임에 프레임이있어서 비어있는 공간을 터치하면 사용자 지정보기가 표시됩니다. 사용자가 풍선을 터치하면 거품이 사라지고 팝업 사운드가 재생됩니다.

내 코드입니다 :

public class BubbleActivity extends Activity { 

// These variables are for testing purposes, do not modify 
private final static int RANDOM = 0; 
private final static int SINGLE = 1; 
private final static int STILL = 2; 
private static int speedMode = RANDOM; 

private static final String TAG = "Lab-Graphics"; 

// The Main view 
private RelativeLayout mFrame; 

// Bubble image's bitmap 
private Bitmap mBitmap; 

// Display dimensions 
private int mDisplayWidth, mDisplayHeight; 

// Sound variables 

// AudioManager 
private AudioManager mAudioManager; 
// SoundPool 
private SoundPool mSoundPool; 
// ID for the bubble popping sound 
private int mSoundID; 
// Audio volume 
private float mStreamVolume; 

BubbleView bubbleView; 


// Gesture Detector 
private GestureDetector mGestureDetector; 

@Override 
public void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 

    setContentView(R.layout.main); 

    // Set up user interface 
    mFrame = (RelativeLayout) findViewById(R.id.frame); 

    // Load basic bubble Bitmap 
    mBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.b64); 

} 

@Override 
protected void onResume() { 
    super.onResume(); 

    // Manage bubble popping sound 
    // Use AudioManager.STREAM_MUSIC as stream type 

    mAudioManager = (AudioManager) getSystemService(AUDIO_SERVICE); 

    mStreamVolume = (float) mAudioManager 
      .getStreamVolume(AudioManager.STREAM_MUSIC) 
      /mAudioManager.getStreamMaxVolume(AudioManager.STREAM_MUSIC); 

    // TODO - make a new SoundPool, allowing up to 10 streams 
    mSoundPool = new SoundPool(10, AudioManager.STREAM_MUSIC, 0); 

    // TODO - set a SoundPool OnLoadCompletedListener that calls 
    // setupGestureDetector() 
    mSoundPool.setOnLoadCompleteListener(new OnLoadCompleteListener() { 
     @Override 
     public void onLoadComplete(SoundPool soundPool, int sampleId, 
       int status) { 
      if (0 == status) { 
       setupGestureDetector(); 
      } else { 
       Log.i(TAG, "Unable to load sound"); 
       finish(); 
      } 

     } 
    }); 

    // TODO - load the sound from res/raw/bubble_pop.wav 
    mAudioManager.loadSoundEffects(); 

} 

@Override 
public void onWindowFocusChanged(boolean hasFocus) { 
    super.onWindowFocusChanged(hasFocus); 
    if (hasFocus) { 

     // Get the size of the display so this View knows where borders are 
     mDisplayWidth = mFrame.getWidth(); 
     mDisplayHeight = mFrame.getHeight(); 

    } 
} 

// Set up GestureDetector 
private void setupGestureDetector() { 

    mGestureDetector = new GestureDetector(this, 
      new GestureDetector.SimpleOnGestureListener() { 

       // If a fling gesture starts on a BubbleView then change the 
       // BubbleView's velocity 

       @Override 
       public boolean onFling(MotionEvent event1, 
         MotionEvent event2, float velocityX, float velocityY) { 

        // TODO - Implement onFling actions. 
        // You can get all Views in mFrame one at a time 
        // using the ViewGroup.getChildAt() method 
        if (bubbleView.intersects(velocityX, velocityY)) { 
         bubbleView.deflect(velocityX,velocityY); 
        } 

        return true; 
       } 

       // If a single tap intersects a BubbleView, then pop the 
       // BubbleView 
       // Otherwise, create a new BubbleView at the tap's location 
       // and add 
       // it to mFrame. You can get all views from mFrame with 
       // ViewGroup.getChildAt() 

       @Override 
       public boolean onSingleTapConfirmed(MotionEvent event) { 

        // TODO - Implement onSingleTapConfirmed actions. 
        // You can get all Views in mFrame using the 
        // ViewGroup.getChildCount() method 
        mFrame.setOnTouchListener(new OnTouchListener() { 
         public boolean onTouch(View v, MotionEvent event) { 
          switch (event.getActionMasked()) { 

          case MotionEvent.ACTION_DOWN: 

           float pointerX = event.getX(); 
           float pointerY = event.getY(); 
           int pointerIndex = event.getActionIndex(); 
           int pointerID = event.getPointerId(pointerIndex); 

           if (bubbleView.intersects(pointerX,pointerY)) { 
            bubbleView = (BubbleView) mFrame.getChildAt(pointerID); 
            bubbleView.stopMovement(true); 
           } else { 
            bubbleView = new BubbleView(
              getApplicationContext(), 
              mBitmap); 

            mFrame.addView(bubbleView); 
           } 
          } 
          return true; 
         } 
        }); 

        return true; 
       } 
      }); 
} 

@Override 
public boolean onTouchEvent(MotionEvent event) { 

    // TODO - Delegate the touch to the gestureDetector 
    return mGestureDetector.onTouchEvent(event); 

} 

@Override 
protected void onPause() { 

    // TODO - Release all SoundPool resources 
    if (null != mSoundPool) { 
     mSoundPool.unload(mSoundID); 
     mSoundPool.release(); 
     mSoundPool = null; 
    } 

    mAudioManager.setSpeakerphoneOn(false); 
    mAudioManager.unloadSoundEffects(); 
    super.onPause(); 
} 

// BubbleView is a View that displays a bubble. 
// This class handles animating, drawing, and popping amongst other actions. 
// A new BubbleView is created for each bubble on the display 

public class BubbleView extends View { 

    private static final int BITMAP_SIZE = 64; 
    private static final int REFRESH_RATE = 40; 
    private final Paint mPainter = new Paint(); 
    private ScheduledFuture<?> mMoverFuture; 
    private int mScaledBitmapWidth; 
    private Bitmap mScaledBitmap; 

    // location, speed and direction of the bubble 
    private float mXPos, mYPos, mDx, mDy, mRadius, mRadiusSquared; 
    private long mRotate, mDRotate; 

    BubbleView(Context context, float x, float y) { 
     super(context); 

     // Create a new random number generator to 
     // randomize size, rotation, speed and direction 
     Random r = new Random(); 

     // Creates the bubble bitmap for this BubbleView 
     createScaledBitmap(r); 

     // Radius of the Bitmap 
     mRadius = mScaledBitmapWidth/2; 
     mRadiusSquared = mRadius * mRadius; 

     // Adjust position to center the bubble under user's finger 
     mXPos = x - mRadius; 
     mYPos = y - mRadius; 

     // Set the BubbleView's speed and direction 
     setSpeedAndDirection(r); 

     // Set the BubbleView's rotation 
     setRotation(r); 

     mPainter.setAntiAlias(true); 

    } 

    public BubbleView(Context applicationContext, Bitmap mBitmap) { 
     // TODO Auto-generated constructor stub 
     super(getBaseContext()); 
    } 

    private void setRotation(Random r) { 
     if (speedMode == RANDOM) { 

      // TODO - set rotation in range [1..3] 
      mDRotate = r.nextInt(3); 
      //mDRotate = r.nextInt(n) 

     } else { 
      mDRotate = 0; 
     } 
    } 

    private void setSpeedAndDirection(Random r) { 

     // Used by test cases 
     switch (speedMode) { 

     case SINGLE: 

      mDx = 20; 
      mDy = 20; 
      break; 

     case STILL: 

      // No speed 
      mDx = 0; 
      mDy = 0; 
      break; 

     default: 

      // TODO - Set mDx and mDy to indicate movement direction and 
      // speed 
      // Limit speed in the x and y direction to [-3..3] pixels per 
      // movement. 

     } 
    } 

    private void createScaledBitmap(Random r) { 

     if (speedMode != RANDOM) { 
      mScaledBitmapWidth = BITMAP_SIZE * 3; 
     } else { 

      // TODO - set scaled bitmap size in range [1..3] * BITMAP_SIZE 
      mScaledBitmapWidth = r.nextInt(3)*BITMAP_SIZE; 

     } 

     // TODO - create the scaled bitmap using size set above 
     mBitmap.createScaledBitmap(mScaledBitmap, mDisplayWidth, mDisplayHeight, false); 
    } 

    // Start moving the BubbleView & updating the display 
    private void startMovement() { 

     // Creates a WorkerThread 
     ScheduledExecutorService executor = Executors 
       .newScheduledThreadPool(1); 

     // Execute the run() in Worker Thread every REFRESH_RATE 
     // milliseconds 
     // Save reference to this job in mMoverFuture 
     mMoverFuture = executor.scheduleWithFixedDelay(new Runnable() { 
      @Override 
      public void run() { 

       // TODO - implement movement logic. 
       // Each time this method is run the BubbleView should 
       // move one step. If the BubbleView exits the display, 
       // stop the BubbleView's Worker Thread. 
       // Otherwise, request that the BubbleView be redrawn. 
       if(!isOutOfView()){ 
        moveWhileOnScreen(); 
       } 
       else{ 
        stopMovement(true); 
       } 

      } 
     }, 0, REFRESH_RATE, TimeUnit.MILLISECONDS); 
    } 

    // Returns true if the BubbleView intersects position (x,y) 
    private synchronized boolean intersects(float x, float y) { 

     // TODO - Return true if the BubbleView intersects position (x,y) 
     if ((x>mXPos && x<(mXPos+mScaledBitmapWidth)) && (y>mYPos && y<(mYPos+mScaledBitmapWidth))) { 
      return true; 
     } 
     return false; 

    } 

    // Cancel the Bubble's movement 
    // Remove Bubble from mFrame 
    // Play pop sound if the BubbleView was popped 

    private void stopMovement(final boolean wasPopped) { 

     if (null != mMoverFuture) { 

      if (!mMoverFuture.isDone()) { 
       mMoverFuture.cancel(true); 
      } 

      // This work will be performed on the UI Thread 
      mFrame.post(new Runnable() { 
       @Override 
       public void run() { 

        // TODO - Remove the BubbleView from mFrame 
        mFrame.removeView(BubbleView.this); 
        // TODO - If the bubble was popped by user, 
        // play the popping sound 
        if (wasPopped) { 
         mSoundPool.play(mSoundID, 1, 1, 1, 0, 1); 
        } 
       } 
      }); 
     } 
    } 

    // Change the Bubble's speed and direction 
    private synchronized void deflect(float velocityX, float velocityY) { 
     mDx = velocityX/REFRESH_RATE; 
     mDy = velocityY/REFRESH_RATE; 
    } 

    // Draw the Bubble at its current location 
    @Override 
    protected synchronized void onDraw(Canvas canvas) { 

     // TODO - save the canvas 
     canvas.save(); 
     // TODO - increase the rotation of the original image by mDRotate 
     mRotate = mRotate + mDRotate; 
     // TODO Rotate the canvas by current rotation 
     // Hint - Rotate around the bubble's center, not its position 
     canvas.rotate(mRotate, mXPos + mScaledBitmapWidth/2, mYPos + mScaledBitmapWidth/2); 
     // TODO - draw the bitmap at it's new location 
     canvas.drawBitmap(mScaledBitmap, mXPos, mYPos,mPainter); 
     // TODO - restore the canvas 
     canvas.restore(); 
    } 

    // Returns true if the BubbleView is still on the screen after the move 
    // operation 
    private synchronized boolean moveWhileOnScreen() { 

     // TODO - Move the BubbleView 
     mXPos = mDx+mXPos; 
     mYPos = mDy+mYPos; 

     postInvalidate(); 

     return isOutOfView(); 

    } 

    // Return true if the BubbleView is still on the screen after the move 
    // operation 
    private boolean isOutOfView() { 

     // TODO - Return true if the BubbleView is still on the screen after 
     // the move operation 
     if(mXPos + mScaledBitmapWidth/2 >= mDisplayWidth - mScaledBitmapWidth/2 || mXPos <0 
       ||mYPos + mScaledBitmapWidth/2 >= mDisplayHeight - mScaledBitmapWidth/2 || mYPos <0){ 
      return true; 
     } 
     return false; 

    } 
} 

이는 로그 캣 MSG입니다 :

enter image description here

+1

널 포인터를 BubbleActivity 197에 .. 그 선은 무엇인가? –

+0

'return mGestureDetector.onTouchEvent (event);' –

+0

mGestureDetector가 NULL 일 수 있습니다. –

답변

0

그 어디서든 코드에서 BubbleView의 인스턴스를 craeting하지 않기 때문에. 당신이 클릭에 거품이 아니라 아래 onSingleTapConfirmed()을 수정, 추가 할 이후 :

 @Override 
     public boolean onSingleTapConfirmed(MotionEvent event) { 

      // TODO - Implement onSingleTapConfirmed actions. 
      // You can get all Views in mFrame using the 
      // ViewGroup.getChildCount() method 
      boolean createBubble = true; 
      float x = event.getX(); 
      float y = event.getY(); 
      for(int i = 0 ; i < mFrame.getChildCount(); i++){ 
       BubbleView view = (BubbleView) mFrame.getChildAt(i); 
       if(view.intersects(x, y)){ 
        view.stopMovement(true); 
        createBubble = false; 
       } 
      } 
      if(createBubble){ 
       BubbleView bv = new BubbleView(getApplicationContext(), x, y); 
       mFrame.addView(bv); 
      } 

      return true; 
     } 
    }); 
}