我试图创建一个简单的应用程序,在按下一个按钮时绘制随机圆圈,并在按下另一个按钮时将它们全部从屏幕上清除。目前,当我出于某种原因在模拟器上启动应用程序时,它以自动生成的圆圈开始,然后如果我尝试按下按钮生成另一个圆圈,应用程序崩溃,我的< NullPointerException / p>
c.drawcircle(b.getX(), b.getY(), b.getR(), p)
方法
这是我目前所拥有的:
主:
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存储我制作的所有气泡,然后使用clear按钮清除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%确定为什么会这样。
答案 0 :(得分:0)
你将null传递给你的方法onDraw:
dv.onDraw(null);
我猜你想在那里传递Canvas。
在此方法中,您的Canvas将指向null,因为您将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!
}
==&GT; NPE
答案 1 :(得分:0)
至于你的随机方法试试这个
Random rng = new Random();
在您的字段声明中。
然后使用。 rng.nextInt(255);color = Color.rgb(rng.nextInt(255), rng.nextInt(255), rng.nextInt(255));
至于你的圈子:首先你需要一个更新方法(如果你想要任何动作) 其次你应该使用surfaceView绘制,第三,你应该使用a 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>
这是一个livewallpaper创建圈子onTouch ...随意玩它,你应该在这里找到你需要的东西....
注意:您可能需要更改清单中的包名称才能运行它!