Android按钮初始化但无法正常工作

时间:2017-02-25 18:00:54

标签: java android android-layout

我在3 X 3网格中有9个按钮用于井字游戏应用程序。以下是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
    }

现在的问题是,在设置按钮时调用的构造函数中的Log.d工作正常并打印到Logcat但单击按钮时onClick函数不起作用。对于onClick函数,没有显示Log.d和toast。

任何帮助都将不胜感激。

2 个答案:

答案 0 :(得分:1)

简答:

您的观点不在层次结构中

长答案/解决方案(解决问题的正确方法):

您遇到此问题,因为onClickListeners on的视图实际上并未附加到视图层次结构。

这可以通过永远不像你在这里的inflater中使用null来轻松避免:

inflater.inflate(R.layout.board_layout, null);

无论如何它都会在inflater中跳过一段有用的代码,并且已经有了等待附加到你需要的地方的规定(即在适配器中):

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);

同时删除对setContentView的第二次调用:

boardCells[0][0] = (Button) findViewById(R.id.cellOne);

第二个电话是在屏幕上添加一个新的充气套装(不使用你附加听众的那套)

这里还有其他一些小错误。 Java总是使用基于零的数组(因此元素是[0],[1],[2] ......不是[1],[2] ......)。您的电路板分配会浪费内存 - 您的布局中有3x3网格但是4x4阵列

setContentView(R.layout.board_layout);

当你使用上面的循环时,你只使用数组中的一些项目(下面的x)。零是空的浪费元素

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++)

另一个注意事项(只是为了省力)。任何时候你用字符串连接任何东西,它都会被你强制转换成一个字符串(自动原语,对象自动通过它们的toString方法),因此对于日志记录,以下都是相同的:

0 | 0 | 0 | 0
- - - - - - -
0 | x | x | x
- - - - - - -
0 | x | x | x
- - - - - - -
0 | x | x | x

简短解决方案(黑客)

当且仅当你不明白我刚刚解释的内容时。然后你可以通过改变

来修复它
Log.d("TAG1", Float.toString(x) + " " + Float.toString(y));
Log.d("TAG1", new Float(x) + " " + new Float(y));
Log.d("TAG1", x + " " + y);

setContentView(R.layout.board_layout);

答案 1 :(得分:-1)

你不应该使用该代码,

boardCells[i][j].setOnClickListener(new MyClickListener(i, j));

我认为,错误从这里开始。

你可以,

boardCells[i][j].setOnClickListener(new OnClickListener(....
Log.d("Testing","Clicked : " + i + "-" + j);
...)