[英]Getting NPE (Edited)
我仍在获取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):在As2.packageTK.TicTacToeGame.onCreate(TicTacToeGame .java:88)
第88行是:
doneP1.setOnClickListener(this);
我已经为此工作了大约4个小时,但仍然无法解决一个简单的问题。 我的头流口水,我真的很累,我想在入睡之前解决这个问题,以便快速响应。 我清理并重建了问题,没事。 一切似乎都很好,但是没有... NPE总是要破产。
如果您获得了NPE
doneP1.setOnClickListener(this);
这意味着doneP1为空。 您是否仅通过打印/登录doneP1,doneP2,resetP1和resetP2进行了检查(当然在第88行之前)。 例如:
Log.d(TAG, "doneP1 = "+doneP1);
Log.d(TAG, "doneP2 = "+doneP2);
...
我的猜测是所有这些组件都是空的。 这意味着您可能加载了错误的布局。 或者,也许您从一开始就加载了正确的文件,但是您将其更改为其他内容
public void changeLayout(int turn)
编辑:
您的TableRows具有不同的布局?
"Here are the XML(each table rows are from separate XMLs):"
当然,当您加载P2布局时,P1组件将为空,反之亦然。
编辑2:
将引用加载到changeLayout中。 由于您同时只有两个按钮在屏幕上(重置和完成),因此您实际上只需要两个引用(即,您既不需要donep1也不需要donep2)。 然后在更改布局中,将引用更改为正确的按钮。 因此,您需要在按钮的onClick上轮到谁的逻辑。
看起来您正在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
的实现。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.