我的安卓游戏中有3项活动:MainActivity
,OptionActivity
和GameActivity
。我正在尝试将board_view.xml
的元素引入另一个活动,即OptionActivity.java
board_view.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/RelativeLayout1"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<Button
android:id="@+id/cell11"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:layout_marginTop="180dp" />
<Button
android:id="@+id/cell10"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignBaseline="@+id/cell11"
android:layout_alignBottom="@+id/cell11"
android:layout_toLeftOf="@+id/cell11" />
<Button
android:id="@+id/cell12"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignBaseline="@+id/cell11"
android:layout_alignBottom="@+id/cell11"
android:layout_toRightOf="@+id/cell11" />
<Button
android:id="@+id/cell01"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_above="@+id/cell12"
android:layout_alignLeft="@+id/cell11" />
<Button
android:id="@+id/cell21"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignLeft="@+id/cell11"
android:layout_below="@+id/cell11" />
<Button
android:id="@+id/cell00"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignBaseline="@+id/cell01"
android:layout_alignBottom="@+id/cell01"
android:layout_alignLeft="@+id/cell10" />
<Button
android:id="@+id/cell02"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignBottom="@+id/cell01"
android:layout_alignLeft="@+id/cell12" />
<Button
android:id="@+id/cell20"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignBaseline="@+id/cell21"
android:layout_alignBottom="@+id/cell21"
android:layout_alignRight="@+id/cell10" />
<Button
android:id="@+id/cell22"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignBaseline="@+id/cell21"
android:layout_alignBottom="@+id/cell21"
android:layout_alignLeft="@+id/cell12" />
</RelativeLayout>
我正在使用此代码将board_view.xml
中的元素提取到OptionActivity.java
:
Button tiles[][];
public Button[][] getTiles() {
tiles[0][0] = (Button) findViewById(R.id.cell00);
tiles[0][1] = (Button) findViewById(R.id.cell01);
tiles[0][2] = (Button) findViewById(R.id.cell02);
tiles[1][0] = (Button) findViewById(R.id.cell10);
tiles[1][1] = (Button) findViewById(R.id.cell11);
tiles[1][2] = (Button) findViewById(R.id.cell12);
tiles[2][0] = (Button) findViewById(R.id.cell20);
tiles[2][1] = (Button) findViewById(R.id.cell21);
tiles[2][2] = (Button) findViewById(R.id.cell22);
return tiles;
}
我在旋转器点击事件中使用这些图块,如下所示:
private void spinnerListener() {
spinner1.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
@Override
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
String s = parent.getItemAtPosition(position).toString();
if (s.equalsIgnoreCase("easy")) {
tiles[0][0].setOnClickListener(new OnClickListener() {
public void onClick(View v) {
model.playerMove(0, 0);
}
});
tiles[0][1].setOnClickListener(new OnClickListener() {
public void onClick(View v) {
model.playerMove(0, 1);
}
});
tiles[0][2].setOnClickListener(new OnClickListener() {
public void onClick(View v) {
model.playerMove(0, 2);
}
});
tiles[1][0].setOnClickListener(new OnClickListener() {
public void onClick(View v) {
model.playerMove(1, 0);
}
});
tiles[1][1].setOnClickListener(new OnClickListener() {
public void onClick(View v) {
model.playerMove(1, 1);
}
});
tiles[1][2].setOnClickListener(new OnClickListener() {
public void onClick(View v) {
model.playerMove(1, 2);
}
});
tiles[2][0].setOnClickListener(new OnClickListener() {
public void onClick(View v) {
model.playerMove(2, 0);
}
});
tiles[2][1].setOnClickListener(new OnClickListener() {
public void onClick(View v) {
model.playerMove(2, 1);
}
});
tiles[2][2].setOnClickListener(new OnClickListener() {
public void onClick(View v) {
model.playerMove(2, 2);
}
});
} else if (s.equalsIgnoreCase("intermediate")) {
tiles[0][0].setOnClickListener(new OnClickListener() {
public void onClick(View v) {
model.playerMove(0, 1);
}
});
tiles[0][1].setOnClickListener(new OnClickListener() {
public void onClick(View v) {
model.playerMove(0, 0);
}
});
tiles[0][2].setOnClickListener(new OnClickListener() {
public void onClick(View v) {
model.playerMove(0, 2);
}
});
tiles[1][0].setOnClickListener(new OnClickListener() {
public void onClick(View v) {
model.playerMove(1, 1);
}
});
tiles[1][1].setOnClickListener(new OnClickListener() {
public void onClick(View v) {
model.playerMove(1, 0);
}
});
tiles[1][2].setOnClickListener(new OnClickListener() {
public void onClick(View v) {
model.playerMove(1, 2);
}
});
tiles[2][0].setOnClickListener(new OnClickListener() {
public void onClick(View v) {
model.playerMove(2, 1);
}
});
tiles[2][1].setOnClickListener(new OnClickListener() {
public void onClick(View v) {
model.playerMove(2, 0);
}
});
tiles[2][2].setOnClickListener(new OnClickListener() {
public void onClick(View v) {
model.playerMove(2, 2);
}
});
} else if (s.equalsIgnoreCase("difficult")) {
Toast.makeText(OptionActivity.this, "Difficult", Toast.LENGTH_SHORT).show();
}
}
@Override
public void onNothingSelected(AdapterView<?> parent) {
Toast.makeText(OptionActivity.this, "Please select the difficulty level!", Toast.LENGTH_SHORT).show();
}
});
}
但是当移动设备OptionActivity
加载时,我收到此错误:
02-22 00:47:13.369 8383-8383/com.example.ajaykulkarni.tictactoe E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.ajaykulkarni.tictactoe, PID: 8383
java.lang.NullPointerException: Attempt to read from null array
at com.example.ajaykulkarni.tictactoe.OptionActivity$1.onItemSelected(OptionActivity.java:106)
at android.widget.AdapterView.fireOnSelected(AdapterView.java:931)
at android.widget.AdapterView.dispatchOnItemSelected(AdapterView.java:920)
at android.widget.AdapterView.access$300(AdapterView.java:55)
at android.widget.AdapterView$SelectionNotifier.run(AdapterView.java:890)
at android.os.Handler.handleCallback(Handler.java:743)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:150)
at android.app.ActivityThread.main(ActivityThread.java:5621)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:794)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:684)
如何将其他布局中的按钮阵列拉到另一个活动?
的 EDIT:
OptionActivity:
public class OptionActivity extends Activity implements Observer {
Model model;
Button start_game;
Button one_player;
RadioGroup group;
RadioButton player1_turn;
RadioButton player2_turn;
EditText player1_name;
EditText player2_name;
Spinner spinner1;
Button tiles[][];
public Button[][] getTiles() {
tiles[0][0] = (Button) findViewById(R.id.cell00);
tiles[0][1] = (Button) findViewById(R.id.cell01);
tiles[0][2] = (Button) findViewById(R.id.cell02);
tiles[1][0] = (Button) findViewById(R.id.cell10);
tiles[1][1] = (Button) findViewById(R.id.cell11);
tiles[1][2] = (Button) findViewById(R.id.cell12);
tiles[2][0] = (Button) findViewById(R.id.cell20);
tiles[2][1] = (Button) findViewById(R.id.cell21);
tiles[2][2] = (Button) findViewById(R.id.cell22);
return tiles;
}
public Model getModel() {
return model;
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
/*setContentView(R.layout.activity_option);*/
setContentView(R.layout.activity_option);
setTitle("Tic-Tac-Toe");
Log.d("Tic-Tac-Toe", "Game Option constructor");
// setup the model
model = new Model();
model.addObserver(this);
// setup the radio buttons and radio group
group = (RadioGroup) findViewById(R.id.select_turn);
player1_turn = (RadioButton) findViewById(R.id.player1_turn);
player2_turn = (RadioButton) findViewById(R.id.player2_turn);
// setup the edit texts
player1_name = (EditText) findViewById(R.id.player1_name);
player2_name = (EditText) findViewById(R.id.player2_name);
// setup the game mode buttons
one_player = (Button) findViewById(R.id.one_player);
// register the controller
this.registerController();
/*spinner functionalities*/
this.addSpinner();
this.spinnerListener();
}
private void addSpinner() {
spinner1 = (Spinner) findViewById(R.id.spinner1);
ArrayAdapter<String> arrayAdapter = new ArrayAdapter<String>(this, R.layout.support_simple_spinner_dropdown_item, R.id.spinner1);
arrayAdapter.setDropDownViewResource(R.layout.support_simple_spinner_dropdown_item);
}
private void spinnerListener() {
spinner1.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
@Override
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
String s = parent.getItemAtPosition(position).toString();
if (s.equalsIgnoreCase("easy")) {
tiles[0][0].setOnClickListener(new OnClickListener() {
public void onClick(View v) {
model.playerMove(0, 0);
}
});
tiles[0][1].setOnClickListener(new OnClickListener() {
public void onClick(View v) {
model.playerMove(0, 1);
}
});
tiles[0][2].setOnClickListener(new OnClickListener() {
public void onClick(View v) {
model.playerMove(0, 2);
}
});
tiles[1][0].setOnClickListener(new OnClickListener() {
public void onClick(View v) {
model.playerMove(1, 0);
}
});
tiles[1][1].setOnClickListener(new OnClickListener() {
public void onClick(View v) {
model.playerMove(1, 1);
}
});
tiles[1][2].setOnClickListener(new OnClickListener() {
public void onClick(View v) {
model.playerMove(1, 2);
}
});
tiles[2][0].setOnClickListener(new OnClickListener() {
public void onClick(View v) {
model.playerMove(2, 0);
}
});
tiles[2][1].setOnClickListener(new OnClickListener() {
public void onClick(View v) {
model.playerMove(2, 1);
}
});
tiles[2][2].setOnClickListener(new OnClickListener() {
public void onClick(View v) {
model.playerMove(2, 2);
}
});
} else if (s.equalsIgnoreCase("intermediate")) {
tiles[0][0].setOnClickListener(new OnClickListener() {
public void onClick(View v) {
model.playerMove(0, 1);
}
});
tiles[0][1].setOnClickListener(new OnClickListener() {
public void onClick(View v) {
model.playerMove(0, 0);
}
});
tiles[0][2].setOnClickListener(new OnClickListener() {
public void onClick(View v) {
model.playerMove(0, 2);
}
});
tiles[1][0].setOnClickListener(new OnClickListener() {
public void onClick(View v) {
model.playerMove(1, 1);
}
});
tiles[1][1].setOnClickListener(new OnClickListener() {
public void onClick(View v) {
model.playerMove(1, 0);
}
});
tiles[1][2].setOnClickListener(new OnClickListener() {
public void onClick(View v) {
model.playerMove(1, 2);
}
});
tiles[2][0].setOnClickListener(new OnClickListener() {
public void onClick(View v) {
model.playerMove(2, 1);
}
});
tiles[2][1].setOnClickListener(new OnClickListener() {
public void onClick(View v) {
model.playerMove(2, 0);
}
});
tiles[2][2].setOnClickListener(new OnClickListener() {
public void onClick(View v) {
model.playerMove(2, 2);
}
});
} else if (s.equalsIgnoreCase("difficult")) {
Toast.makeText(OptionActivity.this, "Difficult", Toast.LENGTH_SHORT).show();
}
}
@Override
public void onNothingSelected(AdapterView<?> parent) {
Toast.makeText(OptionActivity.this, "Please select the difficulty level!", Toast.LENGTH_SHORT).show();
}
});
}
BoardView.java:
public class BoardView extends RelativeLayout implements Observer {
Model model;
Button tiles[][];
public BoardView(Context context, Model m) {
super(context);
Log.d("Tic-Tac-Toe", "BoardView constructor");
View.inflate(context, R.layout.board_view, this);
// save the model reference
model = m;
// add this view to model's list of observers
model.addObserver(this);
// get a reference to widgets to manipulate on update
tiles = new Button[3][3];
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 3; j++) {
String row = Integer.toString(i);
String col = Integer.toString(j);
String tileId = "cell" + row + col;
int id = getResources().getIdentifier(tileId, "id",
getContext().getPackageName());
tiles[i][j] = (Button) findViewById(id);
tiles[i][j].setFocusable(false);
tiles[i][j].getBackground().setColorFilter(Color.WHITE,
PorterDuff.Mode.MULTIPLY);
}
}
this.registerControllers();
}
/* the controller part */
private void registerControllers() {
tiles[0][0].setOnClickListener(new OnClickListener() {
public void onClick(View v) {
model.playerMove(0, 0);
}
});
tiles[0][1].setOnClickListener(new OnClickListener() {
public void onClick(View v) {
model.playerMove(0, 1);
}
});
tiles[0][2].setOnClickListener(new OnClickListener() {
public void onClick(View v) {
model.playerMove(0, 2);
}
});
tiles[1][0].setOnClickListener(new OnClickListener() {
public void onClick(View v) {
model.playerMove(1, 0);
}
});
tiles[1][1].setOnClickListener(new OnClickListener() {
public void onClick(View v) {
model.playerMove(1, 1);
}
});
tiles[1][2].setOnClickListener(new OnClickListener() {
public void onClick(View v) {
model.playerMove(1, 2);
}
});
tiles[2][0].setOnClickListener(new OnClickListener() {
public void onClick(View v) {
model.playerMove(2, 0);
}
});
tiles[2][1].setOnClickListener(new OnClickListener() {
public void onClick(View v) {
model.playerMove(2, 1);
}
});
tiles[2][2].setOnClickListener(new OnClickListener() {
public void onClick(View v) {
model.playerMove(2, 2);
}
});
}
第OptionActivity.java:106
行是:
tiles[0][0].setOnClickListener(new OnClickListener() {
答案 0 :(得分:1)
错误消息的直接问题和原因是您永远不会在OptionActivity
中初始化数组:
Button tiles[][];
即使你提及&#34;另一项活动&#34;在您的问题中,您似乎拥有自定义视图BoardView
和单个活动OptionActivity
。 Activity
应将BoardView
视为一个完整的实体,并且永远不会直接访问其内部组件,包括单个子视图。相反,BoardView
应该提供适当的方法,允许非常受控的交互。如果您正确执行此操作,则活动只会进行一次findViewById()
调用,以便从布局中获取BoardView
。
回顾评论
OptionActivity
不应该知道BoardView
不是其内部运作。相反,它应该只负责设置首选项并保存它们。您很可能应该使用SharedPreferences
。使用PreferenceActivity
会有很大帮助。
现在,您的MainActivity
将从SharedPreferences
加载选项并将其传递给BoardView
。 &#34;适当的方法&#34;我之前提到的将是一个或多个setter方法。
BoardView
包含游戏操作的代码,受OptionActivity
中选择的选项的影响。
请注意,根据我的建议,BoardView
受选项的值影响,但不受这些值来自何处的影响。这提供了很大的灵活性。此外,OptionActivity
完全不受BoardView
的影响,至少不会直接影响。
如果有很多选项,您应该考虑将相关的选项分组到一个或多个类中。