2017-02-25 68 views
-2

对于井字游戏应用程序,我在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构造方法中调用,同时设置按钮为w操作正常并打印到Logcat,但点击按钮时onClick函数不起作用。 onClick函数不显示Log.d和toast。

任何帮助,将不胜感激。

+1

数组索引为零,顺便 –

+1

什么的'膨胀()'调用其他解决?您是否将电路板直接膨胀到现有布局?如果不是,那么将充气板添加到现有布局的哪个位置?你确定你正在设置听众的'View'实际上是屏幕上的电路板吗? –

+0

尝试使用'@Override public void onClick'来强制编译器使用该方法 –

回答

-1

您should'nt使用该代码,

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

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

可以,

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

那里没有错。你的答案只是一个应该完成的步骤来调试 –

1

简短的回答:

你的看法并不在层次结构

长的答案/解决方案(右修复它的方式):

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

这可以通过吹气从未使用空很容易地避免像你在这里:

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

它跳过的代码有用块充气不管怎样,已经有等待附加一个条款在需要(即,在适配器):当您传递null作为第二个参数

inflater.inflate(R.layout.board_layout, parent, false); 

,膨胀的观点不附着到层次除非手动这样做。

但是,在你的情况下,没有必要膨胀的布局。你在一个活动,所以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); 

简短的解决方案(一黑客)

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

setContentView(R.layout.board_layout); 

setContentView(boardView); 
+0

我知道你刚才所做的第一点,以确保与我写的其他代码的兼容性,这就是为什么我故意浪费内存的原因。感谢第二点。但这绝不会回答我的问题。 – Krist

+0

我按照建议编辑了代码,我只是坦率。无论如何,这也是我的错误,我认为代码是正确的,但不知何故onClick()函数不起作用。 – Krist

+0

如果我删除了该代码,则在单击调用setName()的按钮时,该应用程序会崩溃。导致:java.lang.NullPointerException:试图从空数组中读取 at com.example.user.tictactoe_basic.MainActivity.setBoard(MainActivity.java:84) - 此行与boardCells [0] [0] = (Button)findViewById(R.id.cellOne); – Krist