2012-11-18 4 views
-2

내 코드는 괜찮지 만 불행히도 내 코드는 null 포인터 예외를 제공합니다. 나는 findviewbyid 전에 setcontentview를 작성함으로써 일어난다는 것을 알았지 만 그렇게함으로써 내 표면이 업데이트되지 않는다. 나는 이것에 대해 많은 조사를 해봤지만 적절한 답변을 얻을 수 없다. 나를 도와주게. 나의 지각을위한 나의 코드 : -표면보기 + 버튼 findviewbyid가 null을 반환합니다.

package com.example.snakes; 

public class MainActivity extends Activity implements View.OnClickListener{ 

MySurfaceClass sc; 
Button up,down,left,right; 
//View v1,v2; 

@Override 
public void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,WindowManager.LayoutParams.FLAG_FULLSCREEN); 
    requestWindowFeature(Window.FEATURE_NO_TITLE); 
    sc = new MySurfaceClass(this); 
    //setContentView(R.layout.activity_main); 

    up = (Button) findViewById(R.id.button1); 
    down = (Button) findViewById(R.id.button2); 
    left = (Button) findViewById(R.id.button3); 
    right = (Button) findViewById(R.id.button4); 

    up.setOnClickListener(this); 
    down.setOnClickListener(this); 
    left.setOnClickListener(this); 
    right.setOnClickListener(this); 
    setContentView(R.layout.activity_main); 

    // Toast.makeText(this, "done", Toast.LENGTH_SHORT).show(); 
} 

@Override 
public boolean onCreateOptionsMenu(Menu menu) { 
    getMenuInflater().inflate(R.menu.activity_main, menu); 
    return true; 
} 

public void onClick(View v) { 
    switch(v.getId()){ 
    case R.id.button1: 
     sc.posY = sc.posY - 50 ; 
     Toast.makeText(this, "up", Toast.LENGTH_SHORT).show(); 
    // sc = new MySurfaceClass(this); 
     // setContentView(R.layout.activity_main); 
     break; 

    case R.id.button2: 
     sc.posY = sc.posY + 50 ; 
     Toast.makeText(this, "down", Toast.LENGTH_SHORT).show(); 
     // sc = new MySurfaceClass(this); 
     //setContentView(R.layout.activity_main); 
     break; 

    case R.id.button3: 
     sc.posX = sc.posX - 50 ; 
     Toast.makeText(this, "left", Toast.LENGTH_SHORT).show(); 
     //sc = new MySurfaceClass(this); 
     //setContentView(R.layout.activity_main); 
     break; 

    case R.id.button4: 
     sc.posX = sc.posX + 10 ; 
     Toast.makeText(this, "right", Toast.LENGTH_SHORT).show(); 
     //setContentView(R.layout.activity_main); 
     break; 
    } 
} 
} 

동안 표면 활성의 코드 -

package com.example.snakes; 


public class MySurfaceClass extends SurfaceView implements Runnable { 

private SurfaceHolder sh; 
private Thread t = null; 
private boolean isRunning; 
private Bitmap b; 
protected int posX, posY; 

public MySurfaceClass(Context context) { 
    super(context); 
    init(); 
} 

public MySurfaceClass(Context context, AttributeSet attrs) { 
    super(context, attrs); 
    init(); 
} 

public MySurfaceClass(Context context, AttributeSet attrs, int defStyle) { 
    super(context, attrs, defStyle); 
    init(); 
} 

void init() { 
    isRunning = true; 
    b = BitmapFactory.decodeResource(getResources(), R.drawable.face); 
    posX = 0; 
    posY = 0; 
    sh = this.getHolder(); 
    t = new Thread(this); 
    t.start(); 
}; 

@Override 
protected void onDraw(Canvas canvas) { 
    super.onDraw(canvas); 
    canvas.drawRect(100, 100, 100, 100, null); 
} 

public void run() { 
    while (isRunning) { 
     if (!sh.getSurface().isValid()) 
      continue; 

     Canvas c = sh.lockCanvas(); 
     c.drawRGB(5, 150, 10); 
     c.drawBitmap(b, posX, posY, null); 
     sh.unlockCanvasAndPost(c); 
    } 
} 
    } 

및 XML -

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 
android:layout_width="fill_parent" 
android:layout_height="fill_parent" 
android:orientation="vertical" > 



<LinearLayout 
    android:id="@+id/view1" 
    android:layout_width="match_parent" 
    android:layout_height="wrap_content" 
    android:background="@drawable/grey" 
    android:weightSum="100" > 

    <Button 
     android:id="@+id/button1" 
     android:layout_width="wrap_content" 
     android:layout_height="wrap_content" 
     android:text="up" 
     android:layout_weight="25"/> 

    <Button 
     android:id="@+id/button2" 
     android:layout_weight="25" 
     android:layout_width="wrap_content" 
     android:layout_height="wrap_content" 
     android:text="down" /> 

    <Button 
     android:id="@+id/button3" 
     android:layout_weight="25" 
     android:layout_width="wrap_content" 
     android:layout_height="wrap_content" 
     android:text="left" /> 

    <Button 
     android:id="@+id/button4" 
     android:layout_weight="25" 
     android:layout_width="wrap_content" 
     android:layout_height="wrap_content" 
     android:text="right" /> 
</LinearLayout> 

<FrameLayout 
    android:layout_width="match_parent" 
    android:layout_height="match_parent" > 

    <com.example.snakes.MySurfaceClass 
     xmlns:android="http://schemas.android.com/apk/res/android" 
     android:layout_width="fill_parent" 
     android:layout_height="fill_parent" 
     android:id="@+id/surfaceView" 
     /> 
</FrameLayout> 

,745,
+1

"내 코드는 괜찮지 만 불행히도 내 코드는 널 포인터 예외를 제공합니다."- 오히려 코드가 좋지 않다는 것을 의미합니까? :) –

+0

글쎄요, 유감스럽게 생각합니다.하지만 그 전에 setcontentview를 쓰면 오류가 발생하지 않습니다. 이유는 무엇입니까? –

+0

SurfaceView 클래스를 수정 했으므로 문제가 분명하게 나타납니다. –

답변

2

findViewById으로 위젯에 대한 참조를 가져 오기 전에 setContentView 메서드를 호출해야합니다. 그렇지 않으면 클릭 리스너를 버튼에 설정할 때 NullPointerExceptions가 표시됩니다.

버튼을 먼저 작동시킨 다음 표면보기에 대해 걱정할 것입니다.

+0

하지만 버튼은 제대로 작동하지만 findviewbyid 전에 setcontentview를 수행하면보기가 업데이트되지 않습니다. –

+0

예. 버튼 참조를 얻기 전에 setContentView를 호출해야합니다. 그렇지 않으면 NPE가 표시됩니다. SurfaceView와 관련하여 findViewById를 사용하여 컨텐츠 뷰에서 가져 오는 것처럼 보이지는 않지만 실제로 새 인스턴스를 인스턴스화하는 것입니다. –

+0

예 그렇다면 일단 스레드가 시작되면 인스턴스가 변경되고 위치 값이 업데이트되어야합니다.하지만 왜 그렇게되지 않습니까? –

0

코드가 깨졌습니다. 너는 setContentView()에 있어야한다. 그렇지 않으면 아무런 견해도 없다.

+0

하지만 콘텐츠보기를 설정했습니다. –

+0

아니요. 당신은이 주석 처리가되어 있습니다 ->'// setContentView (R.layout.activity_main); ' –

+0

이제 app이 실행되기 전에 setContentView를 작성하면 화면이 업데이트되지 않습니다. –

관련 문제