[英]How do I access views in nested layouts programmatically?
I'm trying to use an ImageView
in my java code that is inside the second RelativeLayout
node in the XML. 我试图在XML的第二个
RelativeLayout
节点内的Java代码中使用ImageView
。 However, I can't get references to the ImageViews
as seen by the setVisibility
method that does not make the images invisible. 但是,无法通过
setVisibility
方法看到的对ImageViews
引用不会使图像不可见。
[DOUBLE EDIT] Here is my revised Activity Class: [DOUBLE EDIT]这是我修订的 Activity Class:
package com.scopelyapplication.tictactoe;
import android.content.Intent;
import android.os.Bundle;
import android.support.v7.app.ActionBar;
import android.support.v7.app.ActionBarActivity;
import android.util.Log;
import android.view.MenuItem;
import android.view.View;
import android.widget.ImageButton;
import android.widget.ImageView;
import android.widget.RelativeLayout;
public class TicTacToeActivity extends ActionBarActivity {
private static final String LOGTAG = "TicTacToeActivity";
private ModelComputerGameHelper comHelp;
boolean humanIsX;
RelativeLayout layout;
ImageView blueX;
ImageView greyX;
ImageView blueO;
ImageView greyO;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
layout = (RelativeLayout)findViewById(R.id.mainLayout);
Log.d(LOGTAG, "onCreate");
//Set up action bar
ActionBar actionBar = getSupportActionBar();
actionBar.setDisplayUseLogoEnabled(false);
actionBar.setDisplayHomeAsUpEnabled(true);
Log.d(LOGTAG, "set action bar");
//Initialize X's and O's
blueX = (ImageView)findViewById(R.id.blueXTopLeft);
greyX = (ImageView)findViewById(R.id.greyXTopLeft);
blueO = (ImageView)findViewById(R.id.blueOTopLeft);
greyO = (ImageView)findViewById(R.id.greyOTopLeft);
Log.d(LOGTAG, "X's and O's initialized");
//Turn off their visibility until one is clicked.
blueX.setVisibility(View.INVISIBLE); //where the NPE occurs
greyX.setVisibility(View.INVISIBLE);
blueO.setVisibility(View.INVISIBLE);
greyO.setVisibility(View.INVISIBLE);
Bundle extras = getIntent().getExtras();
boolean gameIsPVP = extras.getBoolean("gameIsPVP");
humanIsX = extras.getBoolean("humanIsX");
if (gameIsPVP) {
; //in progress
} else {
startComputerGame(humanIsX);
}
}
public void squareOneClick(View imageView) {
char humanPlayer = ' ';
if (humanIsX) {
humanPlayer = 'X';
} else {
humanPlayer = 'O';
}
comHelp.makeMove(humanPlayer, 0);
if (humanPlayer == 'X') {
blueX.setVisibility(View.VISIBLE);
} else {
blueO.setVisibility(View.VISIBLE);
}
updateBoard();
}
public void squareTwoClick(View imageView) {
char humanPlayer = ' ';
if (humanIsX) {
humanPlayer = 'X';
}
else {
humanPlayer = 'O';
}
comHelp.makeMove(humanPlayer, 1);
updateBoard();
}
public void squareThreeClick(View imageView) {
char humanPlayer = ' ';
if (humanIsX) {
humanPlayer = 'X';
}
else {
humanPlayer = 'O';
}
comHelp.makeMove(humanPlayer, 2);
updateBoard();
}
public void squareFourClick(View imageView) {
char humanPlayer = ' ';
if (humanIsX) {
humanPlayer = 'X';
}
else {
humanPlayer = 'O';
}
comHelp.makeMove(humanPlayer, 3);
updateBoard();
}
public void squareFiveClick(View imageView) {
char humanPlayer = ' ';
if (humanIsX) {
humanPlayer = 'X';
}
else {
humanPlayer = 'O';
}
comHelp.makeMove(humanPlayer, 4);
updateBoard();
}
public void squareSixClick(View imageView) {
char humanPlayer = ' ';
if (humanIsX) {
humanPlayer = 'X';
}
else {
humanPlayer = 'O';
}
comHelp.makeMove(humanPlayer, 5);
updateBoard();
}
public void squareSevenClick(View imageView) {
char humanPlayer = ' ';
if (humanIsX) {
humanPlayer = 'X';
}
else {
humanPlayer = 'O';
}
comHelp.makeMove(humanPlayer, 6);
updateBoard();
}
public void squareEightClick(View imageView) {
char humanPlayer = ' ';
if (humanIsX) {
humanPlayer = 'X';
}
else {
humanPlayer = 'O';
}
comHelp.makeMove(humanPlayer, 7);
updateBoard();
}
public void squareNineClick(View imageView) {
char humanPlayer = ' ';
if (humanIsX) {
humanPlayer = 'X';
}
else {
humanPlayer = 'O';
}
comHelp.makeMove(humanPlayer, 8);
updateBoard();
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
if (item.getItemId() == android.R.id.home) {
finish();
startActivity(new Intent(this, PickerActivity.class));
}
return super.onOptionsItemSelected(item);
}
public void startComputerGame(boolean isHumanX) {
Log.d(LOGTAG, "startComputerGame");
comHelp = new ModelComputerGameHelper(isHumanX);
updateBoard();
}
public void updateBoard() {
//in progress. connects startComputerGame and Clicks with Visuals.
}
}
And here is some of my XML from activity_main : 这是我来自activity_main的一些XML:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/mainLayout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:minHeight="20dp"
android:minWidth="20dp" >
<ImageView
android:id="@+id/gameBoard"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_alignParentLeft="true"
android:layout_alignParentRight="true"
android:layout_alignParentTop="true"
android:contentDescription="@string/gameboard"
android:src="@drawable/gameboard" />
<RelativeLayout
android:id="@+id/squareOneLayout"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="290dp"
android:layout_marginRight="220dp"
android:layout_marginTop="70dp" >
<ImageButton
android:id="@+id/squareOne"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_alignParentLeft="true"
android:layout_alignParentRight="true"
android:layout_alignParentTop="true"
android:layout_marginBottom="288dp"
android:layout_marginRight="219dp"
android:layout_marginTop="71dp"
android:background="@android:color/transparent"
android:contentDescription="@string/top_left"
android:onClick="squareOneClick"
android:src="@drawable/blank_button" />
<!-- Top-left images -->
<ImageView
android:id="@+id/blueOTopLeft"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignLeft="@+id/greyOTopLeft"
android:layout_centerVertical="true"
android:src="@drawable/piece_o" />
<ImageView
android:id="@+id/greyOTopLeft"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_centerVertical="true"
android:src="@drawable/piece_o_grey" />
<ImageView
android:id="@+id/greyXTopLeft"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignLeft="@+id/blueOTopLeft"
android:layout_centerVertical="true"
android:src="@drawable/piece_x_grey" />
<ImageView
android:id="@+id/blueXTopLeft"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignLeft="@+id/blueOTopLeft"
android:layout_centerVertical="true"
android:src="@drawable/piece_x" />
</RelativeLayout>
... <!-- rest of xml -->
</RelativeLayout>
And here is my logcat, sorry for forgetting! 这是我的日志,对不起,忘记了!
02-23 03:27:26.984: D/AndroidRuntime(1125): Shutting down VM
02-23 03:27:26.984: E/AndroidRuntime(1125): FATAL EXCEPTION: main
02-23 03:27:26.984: E/AndroidRuntime(1125): Process: com.scopelyapplication.tictactoe, PID: 1125
02-23 03:27:26.984: E/AndroidRuntime(1125): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.scopelyapplication.tictactoe/com.scopelyapplication.tictactoe.TicTacToeActivity}: java.lang.NullPointerException
02-23 03:27:26.984: E/AndroidRuntime(1125): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2195)
02-23 03:27:26.984: E/AndroidRuntime(1125): at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2245)
02-23 03:27:26.984: E/AndroidRuntime(1125): at android.app.ActivityThread.access$800(ActivityThread.java:135)
02-23 03:27:26.984: E/AndroidRuntime(1125): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1196)
02-23 03:27:26.984: E/AndroidRuntime(1125): at android.os.Handler.dispatchMessage(Handler.java:102)
02-23 03:27:26.984: E/AndroidRuntime(1125): at android.os.Looper.loop(Looper.java:136)
02-23 03:27:26.984: E/AndroidRuntime(1125): at android.app.ActivityThread.main(ActivityThread.java:5017)
02-23 03:27:26.984: E/AndroidRuntime(1125): at java.lang.reflect.Method.invokeNative(Native Method)
02-23 03:27:26.984: E/AndroidRuntime(1125): at java.lang.reflect.Method.invoke(Method.java:515)
02-23 03:27:26.984: E/AndroidRuntime(1125): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:779)
02-23 03:27:26.984: E/AndroidRuntime(1125): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:595)
02-23 03:27:26.984: E/AndroidRuntime(1125): at dalvik.system.NativeStart.main(Native Method)
02-23 03:27:26.984: E/AndroidRuntime(1125): Caused by: java.lang.NullPointerException
02-23 03:27:26.984: E/AndroidRuntime(1125): at com.scopelyapplication.tictactoe.TicTacToeActivity.onCreate(TicTacToeActivity.java:54)
02-23 03:27:26.984: E/AndroidRuntime(1125): at android.app.Activity.performCreate(Activity.java:5231)
02-23 03:27:26.984: E/AndroidRuntime(1125): at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1087)
02-23 03:27:26.984: E/AndroidRuntime(1125): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2159)
02-23 03:27:26.984: E/AndroidRuntime(1125): ... 11 more
Thank You! 谢谢!
Just access it directly with its ID. 只需直接使用其ID即可访问它。
Change the line to: 将行更改为:
blueX = (ImageView) findViewById(R.id.blueXTopLeft);
and do the similar thing with other related variables and it will then work. 并使用其他相关变量执行类似操作,然后它将起作用。
I think your issue lies within your layout XML. 我认为您的问题出在您的布局XML中。 See the documentation for
RelativeLayout
which states: 请参阅
RelativeLayout
的文档,其中规定:
Note that you cannot have a circular dependency between the size of the RelativeLayout and the position of its children.
请注意,RelativeLayout的大小与其子位置之间不能具有循环依赖关系。 For example, you cannot have a RelativeLayout whose height is set to WRAP_CONTENT and a child set to ALIGN_PARENT_BOTTOM.
例如,您不能将RelativeLayout的高度设置为WRAP_CONTENT,将其子级设置为ALIGN_PARENT_BOTTOM。
You need to correct the circular dependency in squareOneLayout (and possibly elsewhere as well). 您需要更正squareOneLayout中的循环依赖关系(可能还需要更正其他地方)。
A RelativeLayout cannot size itself based on the size of its children, if you want the children to be positioned relative to the parent RelativeLayout. 如果希望子级相对于父级RelativeLayout定位,则RelativeLayout不能根据其子级的大小来调整自身大小。
To put it another way, the parent (RelativeLayout) cannot size itself based on the size and overall layout of its children (ImageViews) if the children are positioned relative to the size of the parent (RelativeLayout). 换句话说,如果父项(RelativeLayout)相对于父项(RelativeLayout)的大小定位,则其父项(RelativeLayout)不能基于其子项(ImageViews)的大小和整体布局调整自身大小。 The result is a circular dependency which cannot be resolved.
结果是无法解决的循环依赖性。
You'll either need to change how the RelativeLayout is sized, or position the ImageViews relative to a sibling view (eg one of the ImageViews) instead of being positioned relative to the parent RelativeLayout. 您要么需要更改RelativeLayout的大小,要么将ImageView相对于同级视图(例如ImageView之一)放置,而不是相对于父级RelativeLayout放置。
As previously stated, have you tried doing a clean on your project? 如前所述,您是否尝试过清洁项目? your R.java could be a little messed up.
您的R.java可能有点混乱。 Project>Clean.
项目>清洁。
Try this... 尝试这个...
activity_main: activity_main:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/mainLayout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:minHeight="20dp"
android:minWidth="20dp" >
<ImageView
android:id="@+id/gameBoard"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_alignParentLeft="true"
android:layout_alignParentRight="true"
android:layout_alignParentTop="true"
android:contentDescription="@string/gameboard"
android:src="@drawable/gameboard" />
<RelativeLayout
android:id="@+id/squareOneLayout"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="290dp"
android:layout_marginRight="220dp"
android:layout_marginTop="70dp" >
<ImageButton
android:id="@+id/squareOne"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_alignParentLeft="true"
android:layout_alignParentRight="true"
android:layout_alignParentTop="true"
android:layout_marginBottom="288dp"
android:layout_marginRight="219dp"
android:layout_marginTop="71dp"
android:background="@android:color/transparent"
android:contentDescription="@string/top_left"
android:onClick="squareOneClick"
android:src="@drawable/blank_button" />
<!-- Top-left images -->
<ImageView
android:id="@+id/blueOTopLeft"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignLeft="@+id/greyOTopLeft"
android:layout_centerVertical="true"
android:src="@drawable/piece_o"
android:visibility="invisible"/>
<ImageView
android:id="@+id/greyOTopLeft"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_centerVertical="true"
android:src="@drawable/piece_o_grey"
android:visibility="invisible"/>
<ImageView
android:id="@+id/greyXTopLeft"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignLeft="@+id/blueOTopLeft"
android:layout_centerVertical="true"
android:src="@drawable/piece_x_grey"
android:visibility="invisible"
/>
<ImageView
android:id="@+id/blueXTopLeft"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignLeft="@+id/blueOTopLeft"
android:layout_centerVertical="true"
android:src="@drawable/piece_x"
android:visibility="invisible"/>
</RelativeLayout>
... <!-- rest of xml -->
</RelativeLayout>
MainActivity.java MainActivity.java
package com.scopelyapplication.tictactoe;
import android.content.Intent;
import android.os.Bundle;
import android.support.v7.app.ActionBar;
import android.support.v7.app.ActionBarActivity;
import android.util.Log;
import android.view.MenuItem;
import android.view.View;
import android.widget.ImageButton;
import android.widget.ImageView;
import android.widget.RelativeLayout;
public class TicTacToeActivity extends ActionBarActivity {
private static final String LOGTAG = "TicTacToeActivity";
private ModelComputerGameHelper comHelp;
boolean humanIsX;
RelativeLayout layout;
ImageView blueX, greyX, blueO, greyO;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
layout = (RelativeLayout)findViewById(R.id.mainLayout);
Log.d(LOGTAG, "onCreate");
//Set up action bar
ActionBar actionBar = getSupportActionBar();
actionBar.setDisplayUseLogoEnabled(false);
actionBar.setDisplayHomeAsUpEnabled(true);
Log.d(LOGTAG, "set action bar");
//Initialize X's and O's
blueX = (ImageView)findViewById(R.id.blueXTopLeft);
greyX = (ImageView)findViewById(R.id.greyXTopLeft);
blueO = (ImageView)findViewById(R.id.blueOTopLeft);
greyO = (ImageView)findViewById(R.id.greyOTopLeft);
Log.d(LOGTAG, "X's and O's initialized");
Bundle extras = getIntent().getExtras();
boolean gameIsPVP = extras.getBoolean("gameIsPVP");
humanIsX = extras.getBoolean("humanIsX");
if (gameIsPVP) {
; //in progress
} else {
startComputerGame(humanIsX);
}
}
public void squareOneClick(View imageView) {
char humanPlayer = ' ';
if (humanIsX) {
humanPlayer = 'X';
} else {
humanPlayer = 'O';
}
comHelp.makeMove(humanPlayer, 0);
if (humanPlayer == 'X') {
blueX.setVisibility(View.VISIBLE);
} else {
blueO.setVisibility(View.VISIBLE);
}
updateBoard();
}
public void squareTwoClick(View imageView) {
char humanPlayer = ' ';
if (humanIsX) {
humanPlayer = 'X';
}
else {
humanPlayer = 'O';
}
comHelp.makeMove(humanPlayer, 1);
updateBoard();
}
public void squareThreeClick(View imageView) {
char humanPlayer = ' ';
if (humanIsX) {
humanPlayer = 'X';
}
else {
humanPlayer = 'O';
}
comHelp.makeMove(humanPlayer, 2);
updateBoard();
}
public void squareFourClick(View imageView) {
char humanPlayer = ' ';
if (humanIsX) {
humanPlayer = 'X';
}
else {
humanPlayer = 'O';
}
comHelp.makeMove(humanPlayer, 3);
updateBoard();
}
public void squareFiveClick(View imageView) {
char humanPlayer = ' ';
if (humanIsX) {
humanPlayer = 'X';
}
else {
humanPlayer = 'O';
}
comHelp.makeMove(humanPlayer, 4);
updateBoard();
}
public void squareSixClick(View imageView) {
char humanPlayer = ' ';
if (humanIsX) {
humanPlayer = 'X';
}
else {
humanPlayer = 'O';
}
comHelp.makeMove(humanPlayer, 5);
updateBoard();
}
public void squareSevenClick(View imageView) {
char humanPlayer = ' ';
if (humanIsX) {
humanPlayer = 'X';
}
else {
humanPlayer = 'O';
}
comHelp.makeMove(humanPlayer, 6);
updateBoard();
}
public void squareEightClick(View imageView) {
char humanPlayer = ' ';
if (humanIsX) {
humanPlayer = 'X';
}
else {
humanPlayer = 'O';
}
comHelp.makeMove(humanPlayer, 7);
updateBoard();
}
public void squareNineClick(View imageView) {
char humanPlayer = ' ';
if (humanIsX) {
humanPlayer = 'X';
}
else {
humanPlayer = 'O';
}
comHelp.makeMove(humanPlayer, 8);
updateBoard();
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
if (item.getItemId() == android.R.id.home) {
finish();
startActivity(new Intent(this, PickerActivity.class));
}
return super.onOptionsItemSelected(item);
}
public void startComputerGame(boolean isHumanX) {
Log.d(LOGTAG, "startComputerGame");
comHelp = new ModelComputerGameHelper(isHumanX);
updateBoard();
}
public void updateBoard() {
//in progress. connects startComputerGame and Clicks with Visuals.
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.