我还在接受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(编辑:new 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总是要陷入其中。
答案 0 :(得分:0)
如果您在
上获得NPEdoneP1.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中加载您的引用。由于您在屏幕上同时只有两个按钮(重置和完成),您实际上只需要两个引用(即您不需要donep1和donep2)。然后在更改布局中,将引用更改为正确的按钮。因此,你需要依次点击按钮的逻辑。
答案 1 :(得分: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
的实施。