Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/183.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 在android中生成随机圆_Java_Android_Canvas_Graphics_Nullpointerexception - Fatal编程技术网

Java 在android中生成随机圆

Java 在android中生成随机圆,java,android,canvas,graphics,nullpointerexception,Java,Android,Canvas,Graphics,Nullpointerexception,我正在尝试制作一个简单的应用程序,当按下一个按钮时,它会随机画出圆圈,当按下另一个按钮时,它会从屏幕上清除所有圆圈。目前,由于某种原因,当我在模拟器上启动应用程序时,它会以自动生成的圆圈开始,然后如果我试图按下按钮生成另一个圆圈,应用程序就会崩溃,我的电脑会出现NullPointerException c.drawcircle(b.getX(), b.getY(), b.getR(), p) 方法 以下是我目前拥有的: 主要内容: drawView: import java.util.Arra

我正在尝试制作一个简单的应用程序,当按下一个按钮时,它会随机画出圆圈,当按下另一个按钮时,它会从屏幕上清除所有圆圈。目前,由于某种原因,当我在模拟器上启动应用程序时,它会以自动生成的圆圈开始,然后如果我试图按下按钮生成另一个圆圈,应用程序就会崩溃,我的电脑会出现NullPointerException

c.drawcircle(b.getX(), b.getY(), b.getR(), p)
方法

以下是我目前拥有的:

主要内容:

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();        
}

}

感谢您的输入,这是我第一次处理图形,所以我无法100%确定为什么会发生这种情况。

您在此处将null传递给您的onDraw方法:

dv.onDraw(null);
我猜你会想把画布放在那里

在此方法中,画布将指向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!
}

==>NPE

至于你的随机方法,试试这个

Random rng = new Random();
在您的字段声明中

然后使用。耐克斯汀(255)

至于你的圈子:首先你需要一个更新方法(如果你想要任何移动) 第二,你应该使用surfaceView来绘制,第三,你应该使用 copyOnWriteArrayList,因为您的按钮在列表上迭代时可能正在修改列表,而copyOnWriteArrayList正适合于此。这是我送给你的礼物

第一类

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);
}



}
import java.util.Random;
导入android.graphics.Canvas;
导入android.graphics.Color;
导入android.graphics.Paint;
导入android.graphics.Paint.Style;
公共阶层成长圈{
浮点x,y;整数半径;
油漆myp=新油漆();
内冷,冷,冷;
int-redvar=1;
int-bluevar=5;
int-greenvar=2;
int脱扣器=10;
int-change=2;
Random rand=新的Random();
公共循环(浮动x,浮动y){
这个.x=x;
这个。y=y;
这个。半径=2;
this.colr=rand.nextInt(254)+1;
this.colg=rand.nextInt(254)+1;
this.colb=rand.nextInt(254)+1;
}
公共无效更新(){
半径+=4;
脱扣器+=更换;
如果(脱扣器=15){
改变=-改变;
}
随机列=新随机();
myp.setColor(Color.argb(255,colr,colg,colb));
colr+=redvar;
colg+=greenvar;
colb+=bluevar;
如果(colr=250){
redvar=-redvar;
}
如果(colg=250){
greenvar=-greenvar;
}
如果(colb=250){
bluevar=-bluevar;
}
}
公共空白绘图(画布){
myp.设定行程宽度(脱扣器);
myp.setStyle(Style.STROKE);
画布绘制圆(x,y,半径,myp);
}
}
类别2

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);
            }
        }

    }
}
import java.util.ArrayList;
导入java.util.List;
导入java.util.Random;
导入java.util.concurrent.CopyOnWriteArrayList;
进口com.gmaninc.acidrain2.R;
导入android.content.SharedReferences;
导入android.graphics.Bitmap;
导入android.graphics.BitmapFactory;
导入android.graphics.Canvas;
导入android.graphics.Color;
导入android.graphics.Paint;
导入android.os.Handler;
导入android.os.SystemClock;
导入android.preference.PreferenceManager;
导入android.service.wallpar.wallperservice;
导入android.service.wallper.wallperservice.Engine;
导入android.view.MotionEvent;
导入android.view.SurfaceHolder;
导入android.view.view;
导入android.view.view.OnTouchListener;
公共类LiveWallperService扩展了WallperService{
CopyOnWriteArrayList gc=新建CopyOnWriteArrayList();
私有最终处理程序mHandler=新处理程序();
@凌驾
public void onCreate(){
super.onCreate();
}
@凌驾
公共空间{
super.ondestory();
}
@凌驾
公共引擎onCreateEngine(){
返回新的立方发动机();
}
类CubeEngine扩展了引擎{
专用最终油漆mPaint=新油漆();
私人浮动货币基金;
私有浮动mTouchX=-1;
私人浮动mTouchY=-1;
私人长时间;
私人浮动mCenterX;
私人浮动麦肯锡;
private final Runnable mDrawCube=new Runnable(){
公开募捐{
牵引架();
}
};
私有布尔mVisible;
立方发动机(){
//创建一个绘画来绘制立方体的线条
最终油漆=mPaint;
paint.setColor(0xffffffff);
paint.setAntiAlias(真);
油漆。设置行程宽度(2);
油漆固定行程盖(油漆固定行程盖圆形);
绘制.设置样式(绘制.样式.笔划);
mStartTime=SystemClock.elapsedRealtime();
}
@凌驾
创建时的公共void(SurfaceHolder SurfaceHolder){
super.onCreate(surfaceHolder);
//默认情况下,我们不会获取触摸事件,因此请启用它们。
setTouchEventsEnabled(真);
}
@凌驾
公共空间{
super.ondestory();
mHandler.removeCallbacks(mDrawCube);
}
@凌驾
公共无效onVisibilityChanged(布尔可见){
mVisible=可见;
如果(可见){
牵引架();
}否则{
mHandler.removeCallbacks(mDrawCube);
}
}
@凌驾
更改了曲面上的公共空白(曲面文件夹持有者、整型格式、整型宽度、整型高度){
super.onSurfaceChanged(支架、格式、宽度、高度);
//存储曲面的中心,以便我们可以在正确的位置绘制立方体
mCenterX=宽度/2.0f;
mCenterY=高度/2.0f;
对于(GrowCirc:gc){
circ.update();
}
牵引架();
}
@凌驾
已创建曲面上的公共空白(曲面持有人){
super.onSurfaceCreated(持有者);
}
@凌驾
表面上的公共空隙已销毁(表面持有人){
super.OnSurface(持有人);
mVisible=false;
mHandler.removeCallbacks(mDrawCube);
}
@凌驾
公共无效OnOffsetChanged(浮动xOffset、浮动yOffset、,
弗洛亚
color = Color.rgb(rng.nextInt(255), rng.nextInt(255), rng.nextInt(255));
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);
}



}
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>