1

私はまだNPEを取得していますが、今はonCreate()からのものです。ボタンを削除すると、すべて正常に動作します。

XML は次のとおりです (各テーブル行は個別の XML からのものです)。

<TableRow
        android:id="@+id/tableRow1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="50dp" >

        <Button
            android:id="@+id/doneP1"
            android:layout_width="50dp"
            android:layout_height="wrap_content"
            android:text="Done" />

        <Button
            android:id="@+id/resetP1"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Reset" />

    </TableRow>

<TableRow
            android:id="@+id/tableRow1"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginTop="50dp" >

            <Button
                android:id="@+id/doneP2"
                android:layout_width="50dp"
                android:layout_height="wrap_content"
                android:text="Done" />

            <Button
                android:id="@+id/resetP2"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="Reset" />

        </TableRow>

コードは次のとおりです。

@Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.tictactoegame);

        /*doneP1 = (Button) this.findViewById(R.id.doneP1);
        doneP2 = (Button) this.findViewById(R.id.doneP2);
        resetP1 = (Button) this.findViewById(R.id.resetP1);
        resetP2 = (Button) this.findViewById(R.id.resetP2);

        checkTurn(); //starts the game

        //buttons
        doneP1.setOnClickListener(this);
        doneP2.setOnClickListener(this);
        resetP1.setOnClickListener(this);
        resetP2.setOnClickListener(this);*/ //commented out 
    }

そしてonCreateの外側

@Override
public void onClick(View v) {
       switch(v.getId()) {
       case R.id.doneP1:
            checkTurn();
           break;
       case R.id.doneP2:
           checkTurn();
           break;
       case R.id.resetP1:
           break;
       case R.id.resetP2:
           break;
       }
}

ここがチェックターン

public void checkTurn()
    {
        if(turn == 1)
        {
            changeLayout(turn);
            turn = 2;
        }
        else
        {
            changeLayout(turn);
            turn = 1;
        }
    }

これがchangelayoutです(編集:新しいchangeLayout、メソッド内の各ボタンを再初期化しましたが、まだ効果がありません。正しくやっていますか?)

public void changeLayout(int turn)
{
    FragmentManager fm       = getSupportFragmentManager();
    Fragment        fragment = fm.findFragmentById(R.id.fragment_container);
    FragmentTransaction ft;

    if(turn == 1) //if its player 1's turn
    {  
        doneP1 = (Button) this.findViewById(R.id.doneP1);
        resetP1 = (Button) this.findViewById(R.id.resetP1);
        doneP1.setOnClickListener(this);
        resetP1.setOnClickListener(this);
        if(fragment == null) //checks wether the current framelayout contains a fragment or not
        {   
            ft = fm.beginTransaction();
            ft.add(R.id.fragment_container, new PlayerTurn1());
            ft.commit(); 
            //setPlayer1();
        }
        else
        {
            ft = fm.beginTransaction();
            ft.replace(R.id.fragment_container, new PlayerTurn1());
            ft.commit();

        }
    }
    else
    {   
        doneP2 = (Button) this.findViewById(R.id.doneP2); 
        resetP2 = (Button) this.findViewById(R.id.resetP2);  
        doneP2.setOnClickListener(this);
        resetP2.setOnClickListener(this);
        if(fragment == null)
        {
            ft = fm.beginTransaction();;
            ft.add(R.id.fragment_container, new PlayerTurn2());
            ft.commit(); 
            //setPlayer2();
        }
        else
        {
            ft = fm.beginTransaction();;
            ft.replace(R.id.fragment_container, new PlayerTurn2());
            ft.commit(); 
        }
    }
}

ここにlogcatがあります

03-24 07:51:55.954: E/AndroidRuntime(5092): 原因: java.lang.NullPointerException 03-24 07:51:55.954: E/AndroidRuntime(5092): At As2.packageTK.TicTacToeGame.onCreate(TicTacToeGame .java:88)

88行目は次のとおりです。

doneP1.setOnClickListener(this);

私はこれに約4時間取り組んでいますが、まだ簡単な問題を解決できません. 頭がよだれを垂らし、とても疲れています。寝る前に直したいので、迅速な対応に感謝します。私は自分の問題をきれいにして再構築しました...何もありません。すべてがうまくいっているように見えますが、そうではありません... NPE は常に破綻しなければなりません。

4

2 に答える 2

0

NPE を装着した場合

doneP1.setOnClickListener(this);

これは、doneP1 が null であることを意味します。doneP1、doneP2、resetP1、およびresetP2を印刷/ログインするだけで確認しましたか(もちろん88行目の前)。例えば:

Log.d(TAG, "doneP1 = "+doneP1);
Log.d(TAG, "doneP2 = "+doneP2);
...

私の推測では、これらのコンポーネントはすべて null です。つまり、間違ったレイアウトをロードしている可能性があります。または、最初から正しいものをロードしても、別のものに変更する場合があります。

public void changeLayout(int turn)

編集:

あなたの TableRows は異なるレイアウトにありますか?

"Here are the XML(each table rows are from separate XMLs):"

もちろん、P2 レイアウトをロードすると P1 コンポーネントは null になり、その逆も同様です。

EDIT2:

参照を changeLayout にロードします。画面には同時に 2 つのボタン (reset と done) しか表示されないため、実際には 2 つの参照のみが必要です (つまり、donep1 と donep2 の両方は必要ありません)。そして、変更レイアウトで、正しいボタンへの参照を変更します。そのため、ボタンの onClick で誰の番だったのかというロジックが必要です。

于 2013-03-24T08:18:42.080 に答える
0

ご覧のとおり、これらのビューを次のように取得していますonCreate

  doneP1 = (Button) this.findViewById(R.id.doneP1);
    doneP2 = (Button) this.findViewById(R.id.doneP2);
    resetP1 = (Button) this.findViewById(R.id.resetP1);
    resetP2 = (Button) this.findViewById(R.id.resetP2);

ただし、次のように変更してレイアウトを変更した後:

public void checkTurn()
{
    if(turn == 1)
    {
        changeLayout(turn);
        turn = 2;
    }
    else
    {
        changeLayout(turn);
        turn = 1;
    }
}

これを実行します:

ft.replace(R.id.fragment_container, new PlayerTurn1());

あなたは基本的にそれらのビューへの参照を失っています。もう存在しないからです。それらは他のフラグメントのビューに置き換えられました。

編集:

onClick別の方法は、レイアウト ファイルでプロパティを設定することです。

をセットする"android:onClick="onDoneButtonOnClick"

アクティビティでメソッドを作成します。

public void onDoneButtonOnClick (View v)
{
      // do here what every you want with this button.
}

この場合onClickListener、アクティビティから の実装を削除する必要があります。

于 2013-03-24T08:26:18.057 に答える