view.getWidth无法正常工作

时间:2014-02-24 16:43:48

标签: android bitmap

我有这一行:

Bitmap bitmap = Bitmap.createBitmap(surface.getWidth(), surface.getHeight(),Bitmap.Config.ARGB_8888);

观点:

LinearLayout surface = new LinearLayout(this);
surface = (LinearLayout)findViewById(R.id.surface);
surface.addView(gv);

当我在surface.getWidth()中放置随机数而不是surface.getHeight() createBitmap时 - 它有效。 我在代码的其他地方使用了surface.getLeft(),但它确实有效。

它出错了,logcat:

02-24 16:39:07.999: E/AndroidRuntime(909): FATAL EXCEPTION: main
02-24 16:39:07.999: E/AndroidRuntime(909): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.snake/com.example.snake.MainActivity}: java.lang.IllegalArgumentException: width and height must be > 0
02-24 16:39:07.999: E/AndroidRuntime(909):  at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2180)
02-24 16:39:07.999: E/AndroidRuntime(909):  at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2230)
02-24 16:39:07.999: E/AndroidRuntime(909):  at android.app.ActivityThread.access$600(ActivityThread.java:141)
02-24 16:39:07.999: E/AndroidRuntime(909):  at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1234)
02-24 16:39:07.999: E/AndroidRuntime(909):  at android.os.Handler.dispatchMessage(Handler.java:99)
02-24 16:39:07.999: E/AndroidRuntime(909):  at android.os.Looper.loop(Looper.java:137)
02-24 16:39:07.999: E/AndroidRuntime(909):  at android.app.ActivityThread.main(ActivityThread.java:5041)
02-24 16:39:07.999: E/AndroidRuntime(909):  at java.lang.reflect.Method.invokeNative(Native Method)
02-24 16:39:07.999: E/AndroidRuntime(909):  at java.lang.reflect.Method.invoke(Method.java:511)
02-24 16:39:07.999: E/AndroidRuntime(909):  at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:793)
02-24 16:39:07.999: E/AndroidRuntime(909):  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:560)
02-24 16:39:07.999: E/AndroidRuntime(909):  at dalvik.system.NativeStart.main(Native Method)
02-24 16:39:07.999: E/AndroidRuntime(909): Caused by: java.lang.IllegalArgumentException: width and height must be > 0
02-24 16:39:07.999: E/AndroidRuntime(909):  at android.graphics.Bitmap.createBitmap(Bitmap.java:687)
02-24 16:39:07.999: E/AndroidRuntime(909):  at android.graphics.Bitmap.createBitmap(Bitmap.java:666)
02-24 16:39:07.999: E/AndroidRuntime(909):  at android.graphics.Bitmap.createBitmap(Bitmap.java:633)
02-24 16:39:07.999: E/AndroidRuntime(909):  at com.example.snake.GameView.<init>(GameView.java:42)
02-24 16:39:07.999: E/AndroidRuntime(909):  at com.example.snake.MainActivity.onCreate(MainActivity.java:39)
02-24 16:39:07.999: E/AndroidRuntime(909):  at android.app.Activity.performCreate(Activity.java:5104)
02-24 16:39:07.999: E/AndroidRuntime(909):  at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1080)
02-24 16:39:07.999: E/AndroidRuntime(909):  at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2144)
02-24 16:39:07.999: E/AndroidRuntime(909):  ... 11 more

EDIT1:

mainActivity代码:

        public class MainActivity extends Activity  {
        GameView gv;

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

            setContentView(R.layout.game_view);
            LinearLayout surface = new LinearLayout(this);
            surface = (LinearLayout)findViewById(R.id.surface);
            gv= new GameView(this,surface);
            surface.addView(gv);
    }

GameView类:

    public class GameView extends SurfaceView implements Runnable {

        private boolean isRunning=false;
        private final long FPS=12;
        int PART_SIZE=6;

        private SurfaceHolder holder;
        Thread snakethread;
        Snake snake;
        Arena a;
        Brick food;
        LinearLayout view;
        Bitmap arena;


    public GameView(Context context,LinearLayout view) {
        super(context);
        this.view=view;
        arena = Bitmap.createBitmap(view.getWidth(), view.getHeight(),Bitmap.Config.ARGB_8888);
        this.a=new Arena();
        snakethread=new Thread(this);
        holder= getHolder();
        this.setBackgroundColor(Color.TRANSPARENT);                 
        this.setZOrderOnTop(true);
        getHolder().setFormat(PixelFormat.TRANSPARENT);

        holder.addCallback(new SurfaceHolder.Callback(){

            @Override
            public void surfaceCreated(SurfaceHolder arg0) {
                setRunning(true);
                snakethread.start();

            }

            @Override
            public void surfaceChanged(SurfaceHolder arg0, int arg1, int arg2,int arg3) {



            }

            @Override
            public void surfaceDestroyed(SurfaceHolder arg0) {

                setRunning(false);

                while(true){
                    try {
                        snakethread.join();
                    } catch (InterruptedException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }
                }
            }
    });
        snake=new Snake(20, 50, "RIGHT",PART_SIZE);
}

    public void run() {
        long stepPerSecond=1000/FPS;
        long startTime;
        long sleepTime;
        Canvas c = null;
        try{
            c=this.getHolder().lockCanvas();
            synchronized (this.getHolder()) {
                ArenaDraw(c);
                }
        }
        catch(Exception e){
        }
        finally{
            if(c!=null){
                this.getHolder().unlockCanvasAndPost(c);
            }
        }
        while(isRunning){
            c=null;
            startTime=System.currentTimeMillis();
            try{
                c=this.getHolder().lockCanvas();
                synchronized (this.getHolder()) {
                    Paint p=new Paint();
                    snakeDraw(c);
                    }
            }
            catch(Exception e){
            }
            finally{
                if(c!=null){
                    this.getHolder().unlockCanvasAndPost(c);
                }
            }
            sleepTime= stepPerSecond-(System.currentTimeMillis()-startTime);
            if(sleepTime>0)
                try {
                    Thread.sleep(sleepTime);
                } catch (InterruptedException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
        }
    }

编辑2:

我补充说:

        setContentView(R.layout.game_view);
    LinearLayout surface = new LinearLayout(this);
    surface = (LinearLayout)findViewById(R.id.surface);
    LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(0, LayoutParams.MATCH_PARENT, 1);
    surface.setLayoutParams(params);
    gv= new GameView(this,surface);
    surface.addView(gv);

我在MainActivity中添加了这个,仍然是同样的错误。我做错了什么?

编辑3:

        LinearLayout surface = new LinearLayout(this);
    surface = (LinearLayout)findViewById(R.id.surface);
    LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(0, LayoutParams.MATCH_PARENT, 1);
    surface.setLayoutParams(params);
    setContentView(R.layout.game_view);
    gv= new GameView(this,surface);
    surface.addView(gv);

2 个答案:

答案 0 :(得分:0)

发生此错误的原因是因为在调用view.getWidth()和view.getHeight()时,它们的值会解析为零,因为该视图尚未膨胀。要解决此问题,您需要对此视图进行充气。所以做这样的事情(会根据你的需要而变化):

LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(0, LayoutParams.MATCH_PARENT, 1); 
// 1 here corresponds to the weight to ensure that it is inflated
// Depending on how you want to split that screen, you will want to assign a weight to the other view as well
surface.setLayoutParams(params);

现在,视图会膨胀,返回的值不会为空。记住不要忘记根据需要设置重量。

答案 1 :(得分:0)

GameView创建实例时,您的LinearLayout尚未绘制。你试图得到不在屏幕上的东西的高度/宽度。

尝试覆盖onLayout方法并获取此方法中的宽度/高度。

或者你可以试试,

LinearLayout.LayoutParams llParams = (LinearLayout.LayoutParams) surface.getLayoutParams();

llParams.widthllParams.height会给你答案。

P.S。在获取参数之前,您可能需要对布局进行膨胀,我还没有对此进行测试。