无法在另一个活动中使用另一个布局元素 - android studio

时间:2017-02-21 19:33:18

标签: java android xml

我的安卓游戏中有3项活动:MainActivityOptionActivityGameActivity。我正在尝试将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() {

1 个答案:

答案 0 :(得分:1)

错误消息的直接问题和原因是您永远不会在OptionActivity中初始化数组:

Button tiles[][];

即使你提及&#34;另一项活动&#34;在您的问题中,您似乎拥有自定义视图BoardView和单个活动OptionActivityActivity应将BoardView视为一个完整的实体,并且永远不会直接访问其内部组件,包括单个子视图。相反,BoardView应该提供适当的方法,允许非常受控的交互。如果您正确执行此操作,则活动只会进行一次findViewById()调用,以便从布局中获取BoardView

回顾评论

OptionActivity不应该知道BoardView不是其内部运作。相反,它应该只负责设置首选项并保存它们。您很可能应该使用SharedPreferences。使用PreferenceActivity会有很大帮助。

现在,您的MainActivity将从SharedPreferences加载选项并将其传递给BoardView。 &#34;适当的方法&#34;我之前提到的将是一个或多个setter方法。

  

BoardView包含游戏操作的代码,受OptionActivity中选择的选项的影响。

请注意,根据我的建议,BoardView受选项的影响,但不受这些值来自何处的影响。这提供了很大的灵活性。此外,OptionActivity完全不受BoardView的影响,至少不会直接影响。

如果有很多选项,您应该考虑将相关的选项分组到一个或多个类中。