我在3 x 3网格中有9个按钮,用于tic-tac-toe应用。这是前三个按钮的board_layout.xml的代码 -
<TableLayout
android:id="@+id/tableLayout1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="20sp" >
<TableRow
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center" >
<Button
android:id="@+id/cellOne"
android:layout_width="90sp"
android:layout_height="98sp"
android:text=""
android:textSize="70sp"
/>
<Button
android:id="@+id/cellTwo"
android:layout_width="90sp"
android:layout_height="98sp"
android:text=""
android:textSize="70sp"
/>
<Button
android:id="@+id/cellThree"
android:layout_width="90sp"
android:layout_height="98sp"
android:text=""
android:textSize="70sp"
/>
</TableRow>
<!and so on for other 6>
现在在我的MainActivity.java中,我有一个函数setboard(),该功能在此屏幕上设置了此布局,并以下来初始化按钮:
private String p1name = "P1";
private String p2name = "P2";
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
public void setName(View view) {
//Function called upon click on some button
// Other code irrelevant to the question
setBoard();
}
}
public void setBoard() {
////////////
LayoutInflater inflater = this.getLayoutInflater();
View boardView = inflater.inflate(R.layout.board_layout, null);
////////////
boardCells = new Button[3][3];
boardCells[0][0] = (Button) boardView.findViewById(R.id.cellOne);
boardCells[0][1] = (Button) boardView.findViewById(R.id.cellTwo);
boardCells[0][2] = (Button) boardView.findViewById(R.id.cellThree);
// Code for other 6 buttons
for (int i = 0; i < 3; i++)
for (int j = 0; j < 3; j++) {
boardCells[i][j].setOnClickListener(new MyClickListener(i, j));
boardCells[i][j].setText("");
boardCells[i][j].setEnabled(false);
}
setContentView(R.layout.board_layout);
TextView tv1 = (TextView) findViewById(R.id.p1Name_board);
tv1.setText(p1name + ":");
tv1 = (TextView) findViewById(R.id.p2Name_board);
tv1.setText(p2name + ":");
turnDisp = (TextView) findViewById(R.id.turnDispString);
turnDisp.setText("Turn of " + p1name);
}
这是myclicklistener类的代码(MainActivity类的内类):
class MyClickListener implements View.OnClickListener {
int x;
int y;
public MyClickListener(int x, int y) {
this.x = x;
this.y = y;
//This Log.d works fine
Log.d("TAG1", Float.toString(x) + " " + Float.toString(y));
}
public void onClick(View view) {
//This Log.d doesn't work
Log.d("TAG2", Float.toString(this.x) + " Hi ");
//This Toast also doesn't work
Toast.makeText(getApplicationContext(), "Pressed", Toast.LENGTH_LONG).show();
//Plus Other code irrelevant to the question
}
现在,问题是在设置按钮工作正常并打印到logcat时log.d in log.d,但是当单击按钮时,onclick函数无法工作。log.d和toast均未显示用于OnClick函数。
任何帮助将不胜感激。
简短答案:
您的观点不在层次结构中
长答案/解决方案(修复它的正确方法):
您正在看到这个问题,因为您的单切列者的视图实际上并未附加到视图层次结构上。
从不在这里像您这样的充气者中使用null,很容易避免这种情况:
inflater.inflate(R.layout.board_layout, null);
它还是跳过了Adflater中的一个有用的代码,并且已经有一项规定等待附加您需要的地方(即在适配器中):
inflater.inflate(R.layout.board_layout, parent, false);
当您将null作为第二个参数传递时,除非您手动这样做,否则夸大的视图不会附加到层次结构。
但是,在您的情况下,无需夸大布局。您正在活动中,因此setContentView()
膨胀并替换布局(但应在onCreate
之后从不调用)。
只需更改onCreate()
中使用的布局,然后在上下文上直接删除inflater.inflate
并直接调用findViewById
:
LayoutInflater inflater = this.getLayoutInflater();
View boardView = inflater.inflate(R.layout.board_layout, null);
boardCells[0][0] = (Button) findViewById(R.id.cellOne);
还将第二个调用删除到setContentView:
setContentView(R.layout.board_layout);
第二个呼叫是在屏幕上添加了一个新的夸大集(不使用您附加侦听器的设置)
这里还有其他一些小错误。Java始终使用基于零的数组(因此元素是[0],[1],[2] ...不是[1],[2] ...)。您正在使用板分配浪费内存 - 布局中有一个3x3网格,但是4x4数组
boardCells = new Button[4][4];
boardCells[1][1] = (Button) boardView.findViewById(R.id.cellOne);
for (int i = 1; i <= 3; i++)
for (int j = 1; j <= 3; j++)
使用上方的循环时,您只使用数组中的某些项目(下面的x)。零是空浪费元素
0 | 0 | 0 | 0
- - - - - - -
0 | x | x | x
- - - - - - -
0 | x | x | x
- - - - - - -
0 | x | x | x
另一个注释(只是为了节省您的精力)。每当您将任何内容与字符串串联时,它都会为您施放到字符串上(原语会自动通过其tostring方法自动对象),因此,用于记录以下内容都是相等的:
Log.d("TAG1", Float.toString(x) + " " + Float.toString(y));
Log.d("TAG1", new Float(x) + " " + new Float(y));
Log.d("TAG1", x + " " + y);
简短解决方案(hack):
,只有当您不明白我刚刚解释的内容时,只有。然后,您可以通过更改
来修复它setContentView(R.layout.board_layout);
to
setContentView(boardView);
您不应该使用该代码,
boardCells[i][j].setOnClickListener(new MyClickListener(i, j));
我认为,错误从这里开始。
你可以,
boardCells[i][j].setOnClickListener(new OnClickListener(....
Log.d("Testing","Clicked : " + i + "-" + j);
...)