英文:
How do I change layout view on the application when i have multiple separate layouts(screens)?
问题
Here's the translated code you provided:
MainActivity layout xml - screen 1
<!-- ... XML layout content ... -->
FoundNum layout xml - screen 2
<!-- ... XML layout content ... -->
MainActivity Java
package com.example.findrandomnumber;
import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.RelativeLayout;
import android.widget.TextView;
import android.widget.Toast;
public class MainActivity extends AppCompatActivity implements View.OnClickListener {
private Button buttonstart, buttonplus, buttonminus, buttoncheck, buttonrestart, buttonrestart1;
private TextView TVcurrentnum, TVshowmessage, tvcounter, tvfoundnum;
private String TAG = "gilog";
private Controllerguessnum myC;
@Override
protected void onCreate(Bundle savedInstanceState) {
// ... Java code ...
}
// ... Other methods ...
public void changepage() {
// ... Java code ...
}
@Override
public void onClick(View v) {
// ... Java code ...
}
}
Controllerguessnum Java
package com.example.findrandomnumber;
public class Controllerguessnum {
// ... Java code ...
}
Modelguessnum Java
package com.example.findrandomnumber;
import java.util.Random;
public class Modelguessnum {
// ... Java code ...
}
Based on the error you're encountering, it seems like the issue is related to changing the layout using setContentView
. To resolve the error, make sure that the layout you're trying to set as content (either page
or grats
layout) is properly inflated and not null.
If you want the layout to change when you find the number, you should use an Intent
to navigate to the next activity (or in your case, the second layout) instead of changing the content view within the same activity. This approach is more standard for transitioning between different screens/layouts.
Also, ensure that you handle the initialization of views and other components correctly in both layout XMLs and the Java code to avoid null references.
英文:
xml mainactivity screen 1
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity"
android:background="#00008b"
android:id="@+id/page"
>
<TextView
android:id="@+id/game"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="The Random Game"
android:textStyle="bold|italic"
android:layout_centerInParent="true"
android:layout_alignParentTop="true"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
android:textColor="#006400"
android:outlineSpotShadowColor="#2196F3"
app:layout_constraintTop_toTopOf="parent" />
<Button
android:id="@+id/buttonstart"
android:text="Start"
android:textStyle="bold|italic"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@id/game"
android:layout_centerInParent="true"
android:textColor="#006400"
android:background="#8b0000"
/>
<TextView
android:id="@+id/TVshowmessage"
android:text="the number is"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@id/buttonstart"
android:layout_centerInParent="true"
android:textColor="#006400"
/>
<Button
android:id="@+id/buttonplus"
android:text="+"
android:textStyle="bold|italic"
android:textSize="@android:dimen/app_icon_size"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@id/TVshowmessage"
android:layout_centerInParent="true"
android:textColor="#006400"
android:background="#8b0000"
/>
<TextView
android:id="@+id/TVcurrentnum"
android:text="0"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@id/buttonplus"
android:layout_centerInParent="true"
android:textColor="#006400"
android:background="#8b0000"
/>
<Button
android:id="@+id/buttonminus"
android:text="-"
android:textSize="@android:dimen/app_icon_size"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@id/TVcurrentnum"
android:layout_centerInParent="true"
android:textColor="#006400"
android:background="#8b0000"
/>
<TextView
android:id="@+id/tvcounter"
android:text="counter"
android:layout_width="wrap_content"
android:layout_height="66dp"
android:layout_centerInParent="true"
android:layout_marginBottom="300dp"
android:background="#8b0000"
android:textColor="#006400"
android:textStyle="bold|italic"
android:textAlignment="center"
android:layout_below="@id/buttonrestart"
/>
<Button
android:id="@+id/buttoncheck"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:layout_centerHorizontal="true"
android:textColor="#006400"
android:background="#8b0000"
android:textStyle="bold|italic"
android:outlineSpotShadowColor="#008B02"
android:text="Check"
android:layout_below="@id/buttonminus"
/>
<Button
android:id="@+id/buttonrestart"
android:text="restart"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:textColor="#006400"
android:background="#8b0000"
android:textStyle="bold|italic"
android:layout_below="@id/buttoncheck"
/>
</RelativeLayout>
foundnum xml screen 2
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#00008b"
android:id="@+id/grats"
>
<TextView
android:id="@+id/tvfound"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="congrats"
android:textColor="#006400"
android:background="#8b0000"
android:textStyle="bold|italic"
android:layout_above="@+id/buttonrestart1"
android:layout_centerInParent="true"
/>
<Button
android:id="@+id/buttonrestart1"
android:text="restart"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:textColor="#006400"
android:background="#8b0000"
android:textStyle="bold|italic"
/>
</RelativeLayout>
main activity java.
package com.example.findrandomnumber;
import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.RelativeLayout;
import android.widget.TextView;
import android.widget.Toast;
public class MainActivity extends AppCompatActivity implements View.OnClickListener {
private Button buttonstart, buttonplus, buttonminus, buttoncheck, buttonrestart,buttonrestart1;
private TextView TVcurrentnum, TVshowmessage, tvcounter,tvfoundnum;
private String TAG = "gilog",currentnum,counter;
private Controllerguessnum myC;
@Override
protected void onCreate(Bundle savedInstanceState) {
Log.d(TAG, "onCreate: hi");
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
buttonstart =(Button) findViewById(R.id.buttonstart);
buttonplus = (Button)findViewById(R.id.buttonplus);
buttonminus =(Button) findViewById(R.id.buttonminus);
buttoncheck = (Button)findViewById(R.id.buttoncheck);
buttonrestart = (Button)findViewById(R.id.buttonrestart);
buttonrestart1 = (Button)findViewById(R.id.buttonrestart1);
TextView tvcounter= findViewById(R.id.tvcounter);
TextView TVshowmessage= findViewById(R.id.TVshowmessage);
TextView TVcurrentnum= findViewById(R.id.TVcurrentnum);
TextView tvfoundnum= findViewById(R.id.tvfound);
findViewById(R.id.page);
findViewById(R.id.grats);
buttonstart.setOnClickListener(this);
buttonrestart.setOnClickListener(this);
buttoncheck.setOnClickListener(this);
buttonplus.setOnClickListener(this);
buttonminus.setOnClickListener(this);
Log.d(TAG, "onCreate: set clickers worked");
}
public void startGame() {
myC = new Controllerguessnum();
Log.d(TAG, "startGame: random number is " + myC.crandom());
}
public void showmessage(){
TextView TVshowmessage= findViewById(R.id.TVshowmessage);
Log.d(TAG, "onClick: button check was pressed");
if (myC.ccheck() == "smaller"){
Log.d(TAG, "onClick: check is ? "+ myC.ccheck() +" numbers: "+myC.ccurrentnum()+ "<"+ myC.crandom());
TVshowmessage.setText("number is smaller than random number" + 0);
}
else
if (myC.ccheck() == "equal"){
Log.d(TAG, "onClick: check is ? "+ myC.ccheck() + "="+ myC.crandom());
TVshowmessage.setText("congrats you found the number, "+String.valueOf(myC.ccounter()/2)+" tries,"+ " press restart to play again" );
}
else {
if(myC.ccheck() == "bigger") {
Log.d(TAG, "onClick: check is ? "+ myC.ccheck() + ">"+ myC.crandom());
TVshowmessage.setText("number you chose is bigger than random number" + 0);
}
}
}
public void changepage(){
TextView tvfoundnum= findViewById(R.id.tvfound);
RelativeLayout grats= findViewById(R.id.grats);
RelativeLayout page= findViewById(R.id.page);
TextView TVshowmessage= findViewById(R.id.TVshowmessage);
if (myC.ccheck() == "equal"){
page.setVisibility(View.GONE);
setContentView(grats);
}
else{
setContentView(page);
}
}
@Override
public void onClick(View v) {
buttonstart =(Button) findViewById(R.id.buttonstart);
buttonplus = (Button)findViewById(R.id.buttonplus);
buttonminus =(Button) findViewById(R.id.buttonminus);
buttoncheck = (Button)findViewById(R.id.buttoncheck);
buttonrestart = (Button)findViewById(R.id.buttonrestart);
TVcurrentnum= findViewById(R.id.TVcurrentnum);
tvcounter= findViewById(R.id.tvcounter);
if (v.getId() == R.id.buttonstart || v.getId() == R.id.buttonrestart) {
startGame();
}
if (v.getId() == R.id.buttonrestart1){
findViewById(R.id.page).setVisibility(View.VISIBLE);
findViewById(R.id.grats).setVisibility(View.GONE);
startGame();
}
//button check
if (v.getId() == R.id.buttoncheck) {
showmessage();
myC.ccntplus();
tvcounter.setText(String.valueOf((int)(myC.ccounter())+ 0));
Log.d(TAG, "onClick: counter returned"+ tvcounter.getText());
changepage();
}
if (v.getId() == R.id.buttonplus) {
Log.d(TAG, "onClick: button plus was pressed");
myC.cplus();
TVcurrentnum.setText(String.valueOf((int)(myC.ccurrentnum()) + 0));
} else if (v.getId() == R.id.buttonminus) {
Log.d(TAG, "onClick: button minus was pressed");
myC.cminus();
TVcurrentnum.setText(String.valueOf((int)(myC.ccurrentnum()) + 0));
}
}
}
there is more code in two other java files but these are not relevant to changing screen but I will add it below.
controller.java
package com.example.findrandomnumber;
public class Controllerguessnum {
private Modelguessnum myModel1;
public double counter=0;
private int random;
public Controllerguessnum(){
myModel1= new Modelguessnum();
cstartGame();
this.counter=0;
}
public void cstartGame(){
myModel1.mStartGame();
this.counter=0; }
public void crestartgame(){
myModel1.mStartGame();
this.counter=0;
}
public void cplus(){
myModel1.mplus();
}
public void cminus(){
myModel1.mminus();
}
public void ccntplus(){
this.counter++;
}
public String ccheck(){
String res = myModel1.mcheck();
return res;
}
public double ccurrentnum(){
int cnum=myModel1.getCurrentnum();
return cnum;
}
public double ccounter(){
double cnt= this.counter;
return cnt;
}
public int crandom(){
this.random = myModel1.getRandomnum();
return this.random;
}
}
model.java
package com.example.findrandomnumber;
import java.util.Random;
public class Modelguessnum {
private int currentnum;
private int randomnum;
private int counter=0;
public Modelguessnum() {
}
public void mStartGame(){
// this.randomnum= new Random().nextInt( 100);
// this.currentnum= new Random().nextInt(100);
this.randomnum=5;
this.currentnum=5;
}
public int getCurrentnum(){
int mnum= currentnum;
return mnum;
}
public int getRandomnum(){
return randomnum;
}
public void mplus(){
this.currentnum++;
}
public void mminus()
{
this.currentnum--;
}
public String mcheck() {
//-1 is smaller
//0 equal
//1 is bigger
if (this.currentnum > this.randomnum) {
return "bigger";
}
else
if (this.currentnum==this.randomnum){
return "equal";
}
else
if(this.currentnum < this.randomnum){
return "smaller";
}
else
return "neither";
}
}
the math part of the code worked fine- any improvements are welcome. - how do I solve the errors so that when I find the number, when the random number = current number and when I press check, I want it to bring me to the second screen/layout(foundnum.xml) - foundnum.xml
the error I get from this is the following:
E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.findrandomnumber, PID: 480
java.lang.IllegalArgumentException: Cannot add a null child view to a ViewGroup
at android.view.ViewGroup.addView(ViewGroup.java:3718)
at android.view.ViewGroup.addView(ViewGroup.java:3700)
at androidx.appcompat.app.AppCompatDelegateImpl.setContentView(AppCompatDelegateImpl.java:687)
at androidx.appcompat.app.AppCompatActivity.setContentView(AppCompatActivity.java:175)
at com.example.findrandomnumber.MainActivity.changepage(MainActivity.java:95)
at com.example.findrandomnumber.MainActivity.onClick(MainActivity.java:129)
at android.view.View.performClick(View.java:4780)
at android.view.View$PerformClick.run(View.java:19866)
at android.os.Handler.handleCallback(Handler.java:739)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:135)
at android.app.ActivityThread.main(ActivityThread.java:5254)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:903)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:698)>
答案1
得分: 1
异常是:无法将空的子视图添加到ViewGroup。
ViewGroup是一个可以包含其他视图的视图。ViewGroup是Android中布局的基类,例如LinearLayout、RelativeLayout、FrameLayout等。换句话说,ViewGroup通常用于定义在Android屏幕上设置/排列/列出视图(小部件)的布局。
你有两个ViewGroup:一个是activity_main.xml
,另一个是foundnum.xml
。
在你的代码(MainActivity)中,你通过这行代码setContentView(R.layout.activity_main);
将activity_main.xml
设置为你的ViewGroup,放在你的onCreate
方法中。
是什么导致了这个错误?
这个错误是由对tvfoundnum
和buttonrestart1
进行操作(设置文本或设置点击操作)引起的:
TextView tvfoundnum = findViewById(R.id.tvfound)
buttonrestart1 = (Button)findViewById(R.id.buttonrestart1);
你对它们设置的任何操作都会导致错误,因为这些视图不是设置的ViewGroup的一部分。换句话说,它们不包含在activity_main.xml
中,也还未被识别。
解决方案选项:
有两种方法可以实现你想要的效果:
- 通过隐藏和显示只想要显示的视图:这意味着你需要将
foundnum.xml
的代码合并到activity_main.xml
中,从而获得一个布局。 - 使用片段(Fragments)。使用片段,一个片段可以管理多个ViewGroup(布局)。
由于你正在使用Activity,我将演示解决方案选项(1)如下:
解决方案一:
这是新的布局(它包含了activity_main.xml
和foundnum.xml
的代码):activity_main.xml。
<!-- 代码已被省略,见上文 -->
注意,当你运行应用程序时,请注意有些视图是隐藏的,即:
<RelativeLayout>
<!-- 页面的相对布局 --> 这是可见的(可见性为 visible )
<!-- 祝贺的相对布局 --> 这是不可见的(可见性为 gone )
</RelativeLayout>
在完成你想要的操作后(检查数字是否在计数器中……),将<!-- 祝贺的相对布局 -->
的可见性设置为可见,将<!-- 页面的相对布局 -->
的可见性设置为隐藏。
你需要修改changepage()
函数中的if语句,类似于这样:
public void changepage(){
if (myC.ccheck().equals("equal")){
page.setVisibility(View.GONE);
grats.setVisibility(View.VISIBLE);
} else {
grats.setVisibility(View.GONE);
page.setVisibility(View.VISIBLE);
}
}
希望你会发现这个有帮助。如果有问题,请留言,我会帮助你解决。
英文:
The exception you getting is that you: Cannot add a null child view to a ViewGroup.
A ViewGroup is a view that can contain other views. The ViewGroup is the base class for Layouts in android, like LinearLayout , RelativeLayout , FrameLayout etc. In other words, ViewGroup is generally used to define the layout in which views(widgets) will be set/arranged/listed on the android screen.
You have two ViewGroups: one activity_main.xml
and foundnum.xml
Within your code (MainActivity), you set activity_main.xml as your viewGroup by this line of code setContentView(R.layout.activity_main);
in your oncreate method.
What causes the error??
The error is caused by taking action(setting text or setting onclick action) on tvfoundnum and buttonrestart1:
TextView tvfoundnum= findViewById(R.id.tvfound)
buttonrestart1 = (Button)findViewById(R.id.buttonrestart1);
Any action you set to them will result into an error because those views are not part of the set ViewGroup. In otherwards they are not contained in activity_main.xml and they are not yet known
Solution Options:
There are 2 ways you can be able to achieve what you want:
- By hiding and displaying only the views you want to display: Meaning you will have to combine foundnum.xml's code to activity_main.xml. Such that you have one layout.
- By using fragments. With fragments, you can have one fragment manage more than one ViewGroup (layouts).
Since you are using activity, I will demonstrate solution option (1) bellow
Solution Option One.
This is the new layout(it contains code from activity_main.xml & foundnum.xml): activity_main.xml.
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity"
>
<RelativeLayout
android:id="@+id/page"
android:layout_width="match_parent"
android:layout_height="match_parent"
>
<TextView
android:id="@+id/game"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:layout_centerInParent="true"
android:outlineSpotShadowColor="#2196F3"
android:text="The Random Game"
android:textColor="#006400"
android:textStyle="bold|italic"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
/>
<Button
android:id="@+id/buttonstart"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@id/game"
android:layout_centerInParent="true"
android:background="#8b0000"
android:text="Start"
android:textColor="#006400"
android:textStyle="bold|italic"
/>
<TextView
android:id="@+id/TVshowmessage"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@id/buttonstart"
android:layout_centerInParent="true"
android:text="the number is"
android:textColor="#006400"
/>
<Button
android:id="@+id/buttonplus"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@id/TVshowmessage"
android:layout_centerInParent="true"
android:background="#8b0000"
android:text="+"
android:textColor="#006400"
android:textSize="@android:dimen/app_icon_size"
android:textStyle="bold|italic"
/>
<TextView
android:id="@+id/TVcurrentnum"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@id/buttonplus"
android:layout_centerInParent="true"
android:background="#8b0000"
android:text="0"
android:textColor="#006400"
/>
<Button
android:id="@+id/buttonminus"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@id/TVcurrentnum"
android:layout_centerInParent="true"
android:background="#8b0000"
android:text="-"
android:textColor="#006400"
android:textSize="@android:dimen/app_icon_size"
/>
<TextView
android:id="@+id/tvcounter"
android:layout_width="wrap_content"
android:layout_height="66dp"
android:layout_below="@id/buttonrestart"
android:layout_centerInParent="true"
android:layout_marginBottom="300dp"
android:background="#8b0000"
android:text="counter"
android:textAlignment="center"
android:textColor="#006400"
android:textStyle="bold|italic"
/>
<Button
android:id="@+id/buttoncheck"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@id/buttonminus"
android:layout_centerHorizontal="true"
android:layout_centerInParent="true"
android:background="#8b0000"
android:outlineSpotShadowColor="#008B02"
android:text="Check"
android:textColor="#006400"
android:textStyle="bold|italic"
/>
<Button
android:id="@+id/buttonrestart"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@id/buttoncheck"
android:layout_centerInParent="true"
android:background="#8b0000"
android:text="restart"
android:textColor="#006400"
android:textStyle="bold|italic"
/>
</RelativeLayout>
<!-- code from foundnm.xml-->
<RelativeLayout
android:id="@+id/grats"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:visibility="gone"
>
<TextView
android:id="@+id/tvfound"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_above="@+id/buttonrestart1"
android:layout_centerInParent="true"
android:background="#8b0000"
android:text="congrats"
android:textColor="#006400"
android:textStyle="bold|italic"
/>
<Button
android:id="@+id/buttonrestart1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:background="#8b0000"
android:text="restart"
android:textColor="#006400"
android:textStyle="bold|italic"
/>
</RelativeLayout>
</RelativeLayout>
Note that, when you run the app take note that some views are hidden, that is
<RelativeLayout>
<!--page relative layout--> This is visible (visibilty = visible )
<!--grats relative layout--> This is invisible (visibility = gone)
</RelativeLayout>
After doing whatever its that you want to do(checking if number is in the counter.....), set visible to <!--grats relative layout-->
and set visibility gone for <!--page relative layout-->
You need to modify the the if statement in this function: changepage(), to something like this
public void changepage(){
if (myC.ccheck() == "equal"){
page.setVisibility(View.GONE);
grats.setVisibility(View.VISIBLE);
}
else{
grats.setVisibility(View.GONE);
page.setVisibility(View.VISIBLE);
}
}
I hope you find this helpful. If you have issues, please comment, I will help you out.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论