2014-03-25 87 views
0

我試圖做一個簡單的應用程序,當一個按鈕被按下時繪製隨機的圓圈,並且當另一個按鈕被按下時將它們全部從屏幕清除。目前,當我由於某種原因,仿真器啓動應用程序啓動自動生成的圈子,那麼如果我試圖按按鈕,生成另一個圈子的應用程序崩潰,我在在android中生成隨機圓圈

c.drawcircle(b.getX(), b.getY(), b.getR(), p) 
得到 NullPointerException異常

方法。

繼承人什麼我目前有:

主營:

import java.util.ArrayList; 
import android.app.Activity; 
import android.os.Bundle; 
import android.view.Menu; 
import android.view.View; 
import android.view.View.OnClickListener; 
import android.widget.Button; 
import android.widget.LinearLayout; 

public class Bubbles extends Activity implements OnClickListener 
{ 
Button b1,b2; 
drawView dv; 
LinearLayout frame; 

@Override 
protected void onCreate(Bundle savedInstanceState) 
{ 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.activity_bubbles); 
    dv = new drawView(getApplicationContext()); 
    frame = (LinearLayout)findViewById(R.id.LinearLayout2); 
    b1 = (Button)findViewById(R.id.BubbleButton); 
    b1.setOnClickListener(this); 
    b2 = (Button)findViewById(R.id.ClearButton); 
    b2.setOnClickListener(this); 
    frame.addView(dv);  
} 

@Override 
public void onClick(View v) 
{ 
    if(v==b1) 
    { 
     dv.onDraw(null); 
    } 
    if(v==b2) 
    { 
     dv.clear();   
    }  
    v.postInvalidate();   
} 


@Override 
public boolean onCreateOptionsMenu(Menu menu) { 

    // Inflate the menu; this adds items to the action bar if it is present. 
    getMenuInflater().inflate(R.menu.bubbles, menu); 
    return true; 
} 

} 

drawView函數:

import java.util.ArrayList; 
import android.content.Context; 
import android.graphics.Canvas; 
import android.graphics.Paint; 
import android.view.View; 

public class drawView extends View 
{ 
ArrayList<Bubble> bList = new ArrayList<Bubble>(); 
Paint p = new Paint(Paint.ANTI_ALIAS_FLAG); 

public drawView(Context con) 
{ 
    super(con); 

} 

public void onDraw(Canvas c) 
{ 
    Bubble b = new Bubble(); 
    p.setColor(b.getColor()); 
    p.setStyle(Paint.Style.FILL); 
    bList.add(b); 
    c.drawCircle(b.getX(), b.getY(), b.getR(), p); 

} 

public void clear() 
{ 
    bList.clear();   
} 

} 

即時通訊使用的ArrayList這個類來存儲所有我做的氣泡,然後清除arrayList使用清除按鈕。 這裏是泡泡類我做了與它去:

泡泡:

import android.graphics.Color; 

public class Bubble 
{ 
int color; 
int y; 
int x; 
int r; 

public Bubble() 
{ 
    color = Color.rgb(rand(0,255), rand(0,255), rand(0,255)); 
    r = rand(0,255); 
    x =rand(0,255); 
    y = rand(0,255); 

} 

public int getColor() { 
    return color; 
} 

public int getY() { 
    return y; 
} 

public int getX() { 
    return x; 
} 

public int getR() { 
    return r; 
} 

/******************************rand()*****************************/ 
public int rand(int a, int b) 
{ 
    return((int)((b-a+1)*Math.random() + a)); 
} 
} 

感謝您的任何投入,這是我第一次與圖形搞亂所以我不是100%肯定,爲什麼發生這種情況。

+1

該行上的哪個變量爲空?使用調試器瀏覽代碼或添加一些日誌語句來弄清楚。 –

回答

0

傳遞null到你的方法OnDraw的位置:

dv.onDraw(null); 

我猜你想要通過一個Canvas那裏。

在這種方法中那麼你的畫布將指向空,因爲你通過null爲帕拉姆:

public void onDraw(Canvas c) { 
    Bubble b = new Bubble(); 
    p.setColor(b.getColor()); 
    p.setStyle(Paint.Style.FILL); 
    bList.add(b); 
    c.drawCircle(b.getX(), b.getY(), b.getR(), p); // c == null here! 
} 

==> NPE

+0

謝謝!我認爲它與此有關,但我不確定如何傳遞Canvas值。我最終在我的主要活動中創建了一個Canvas變量並傳遞給它。解決了錯誤問題,但現在按鈕不做任何事情哈哈。感謝幫助我解決這個問題。 –

+0

我想你想要做的其實是重寫視圖的onDraw方法。你可能想閱讀這裏:http://developer.android.com/training/custom-views/custom-drawing.html – donfuxx

0

爲您隨機方法試試這個

Random rng = new Random(); 

在您的字段聲明中。

然後使用。 rng.nextInt(255);

color = Color.rgb(rng.nextInt(255), rng.nextInt(255), rng.nextInt(255)); 

爲你的社交圈:首先你需要一個更新方法(如果你想要的任何移動) 其次,你應該使用surfaceView畫,第三你應該使用 的CopyOnWriteArrayList,因爲你的按鈕可能修改列表的同時迭代它,copyonwritearraylist對此非常完美。這裏:我的禮物給你。

CLASS 1

import java.util.Random; 

import android.graphics.Canvas; 
import android.graphics.Color; 
import android.graphics.Paint; 
import android.graphics.Paint.Style; 

public class GrowCircle { 
float x, y;int radius; 
Paint myp = new Paint(); 
int colr,colg,colb; 
int redvar=1; 
int bluevar=5; 
int greenvar=2; 
int tripper=10; 
int change=2; 
Random rand = new Random(); 

public GrowCircle(float x, float y){ 
    this.x=x; 
    this.y=y; 
    this.radius=2; 
    this.colr=rand.nextInt(254)+1; 
    this.colg=rand.nextInt(254)+1; 
    this.colb=rand.nextInt(254)+1; 

} 

public void update(){ 
    radius+=4; 
    tripper+=change; 
    if(tripper<=1||tripper>=15){ 
     change=-change; 
    } 
    Random col = new Random(); 
    myp.setColor(Color.argb(255,colr,colg,colb)); 
    colr+=redvar; 
    colg+=greenvar; 
    colb+=bluevar; 

    if(colr<=5||colr>=250){ 
     redvar=-redvar; 
    } 
    if(colg<=5||colg>=250){ 
     greenvar=-greenvar; 
    } 
    if(colb<=5||colb>=250){ 
     bluevar=-bluevar; 
    } 

} 

public void drawThis(Canvas canvas){ 
    myp.setStrokeWidth(tripper); 
    myp.setStyle(Style.STROKE); 
    canvas.drawCircle(x, y, radius, myp); 
} 



} 

CLASS2

import java.util.ArrayList; 
import java.util.List; 
import java.util.Random; 
import java.util.concurrent.CopyOnWriteArrayList; 



import com.gmaninc.acidrain2.R; 





import android.content.SharedPreferences; 
import android.graphics.Bitmap; 
import android.graphics.BitmapFactory; 
import android.graphics.Canvas; 
import android.graphics.Color; 
import android.graphics.Paint; 
import android.os.Handler; 
import android.os.SystemClock; 
import android.preference.PreferenceManager; 
import android.service.wallpaper.WallpaperService; 
import android.service.wallpaper.WallpaperService.Engine; 
import android.view.MotionEvent; 
import android.view.SurfaceHolder; 
import android.view.View; 
import android.view.View.OnTouchListener; 
public class LiveWallpaperService extends WallpaperService { 
    CopyOnWriteArrayList<GrowCircle> gc = new CopyOnWriteArrayList<GrowCircle>(); 
    private final Handler mHandler = new Handler(); 

    @Override 
    public void onCreate() { 
     super.onCreate(); 
    } 

    @Override 
    public void onDestroy() { 
     super.onDestroy(); 
    } 

    @Override 
    public Engine onCreateEngine() { 
     return new CubeEngine(); 
    } 

    class CubeEngine extends Engine { 

     private final Paint mPaint = new Paint(); 
     private float mOffset; 
     private float mTouchX = -1; 
     private float mTouchY = -1; 
     private long mStartTime; 
     private float mCenterX; 
     private float mCenterY; 

     private final Runnable mDrawCube = new Runnable() { 
      public void run() { 
       drawFrame(); 
      } 
     }; 
     private boolean mVisible; 

     CubeEngine() { 
      // Create a Paint to draw the lines for our cube 
      final Paint paint = mPaint; 
      paint.setColor(0xffffffff); 
      paint.setAntiAlias(true); 
      paint.setStrokeWidth(2); 
      paint.setStrokeCap(Paint.Cap.ROUND); 
      paint.setStyle(Paint.Style.STROKE); 

      mStartTime = SystemClock.elapsedRealtime(); 
     } 

     @Override 
     public void onCreate(SurfaceHolder surfaceHolder) { 
      super.onCreate(surfaceHolder); 

      // By default we don't get touch events, so enable them. 
      setTouchEventsEnabled(true); 
     } 

     @Override 
     public void onDestroy() { 
      super.onDestroy(); 
      mHandler.removeCallbacks(mDrawCube); 
     } 

     @Override 
     public void onVisibilityChanged(boolean visible) { 
      mVisible = visible; 
      if (visible) { 
       drawFrame(); 
      } else { 
       mHandler.removeCallbacks(mDrawCube); 
      } 
     } 

     @Override 
     public void onSurfaceChanged(SurfaceHolder holder, int format, int width, int height) { 
      super.onSurfaceChanged(holder, format, width, height); 
      // store the center of the surface, so we can draw the cube in the right spot 
      mCenterX = width/2.0f; 
      mCenterY = height/2.0f; 
      for(GrowCircle circ:gc){ 
       circ.update(); 
      } 
      drawFrame(); 
     } 

     @Override 
     public void onSurfaceCreated(SurfaceHolder holder) { 
      super.onSurfaceCreated(holder); 
     } 

     @Override 
     public void onSurfaceDestroyed(SurfaceHolder holder) { 
      super.onSurfaceDestroyed(holder); 
      mVisible = false; 
      mHandler.removeCallbacks(mDrawCube); 
     } 

     @Override 
     public void onOffsetsChanged(float xOffset, float yOffset, 
       float xStep, float yStep, int xPixels, int yPixels) { 
      mOffset = xOffset; 
      drawFrame(); 
     } 

     /* 
     * Store the position of the touch event so we can use it for drawing later 
     */ 
     @Override 
     public void onTouchEvent(MotionEvent event) { 
      if (event.getAction() == MotionEvent.ACTION_DOWN) { 
       mTouchX = event.getX(); 
       mTouchY = event.getY(); 
      } else { 
       mTouchX = -1; 
       mTouchY = -1; 
      } 
      float tx = event.getX(); 
float ty= event.getY(); 
      gc.add(new GrowCircle(tx,ty)); 
      super.onTouchEvent(event); 
     } 

     /* 
     * Draw one frame of the animation. This method gets called repeatedly 
     * by posting a delayed Runnable. You can do any drawing you want in 
     * here. This example draws a wireframe cube. 
     */ 
     void drawFrame() { 
      final SurfaceHolder holder = getSurfaceHolder(); 

      Canvas c = null; 
      try { 
       c = holder.lockCanvas(); 
       if (c != null) { 
        // draw something 
        drawCircs(c); 
        for(GrowCircle circ:gc){ 
         if(circ.radius>350){ 
          gc.remove(circ); 
         } 
         circ.update(); 
         circ.drawThis(c); 
        } 
        drawTouchPoint(c); 
       } 
      } finally { 
       if (c != null) holder.unlockCanvasAndPost(c); 
      } 

      // Reschedule the next redraw 
      mHandler.removeCallbacks(mDrawCube); 
      if (mVisible) { 
       mHandler.postDelayed(mDrawCube, 1000/25); 
      } 
     } 

     /* 
     * Draw a wireframe cube by drawing 12 3 dimensional lines between 
     * adjacent corners of the cube 
     */ 
     void drawCircs(Canvas c) { 
      c.save(); 
      c.translate(mCenterX, mCenterY); 
      c.drawColor(0xff000000); 

      c.restore(); 
     } 



     /* 
     * Draw a circle around the current touch point, if any. 
     */ 
     void drawTouchPoint(Canvas c) { 
      if (mTouchX >=0 && mTouchY >= 0) { 
       c.drawCircle(mTouchX, mTouchY, 80, mPaint); 
      } 
     } 

    } 
} 

清單

<manifest xmlns:android="http://schemas.android.com/apk/res/android" 
    package="com.gmaninc.acidrain2" 
    android:versionCode="1" 
    android:versionName="1.0" > 

    <uses-sdk 
     android:minSdkVersion="8" 
     android:targetSdkVersion="16" /> 

    <uses-feature 
     android:name="android.software.live_wallpaper" 
     android:required="true" > 
    </uses-feature> 

    <application 
     android:icon="@drawable/ic_launcher" 
     android:label="@string/app_name" 
     android:theme="@style/AppTheme" > 
     <service 
      android:name="LiveWallpaperService" 
      android:enabled="true" 
      android:label="Acid Rain 2" 
      android:permission="android.permission.BIND_WALLPAPER" > 
      <intent-filter> 
       <action android:name="android.service.wallpaper.WallpaperService" > 
       </action> 
      </intent-filter> 

      <meta-data 
       android:name="android.service.wallpaper" 
       android:resource="@xml/mywallpaper" > 
      </meta-data> 
     </service> 

    </application> 

</manifest> 

這是創建圈子onTouch ......隨意玩弄它livewallpaper,你應該找到你需要在這裏...

注意:您可能需要更改清單中的軟件包名稱以使其運行!