简体   繁体   English

如何以编程方式访问嵌套布局中的视图?

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM