Gil Caplan
Gil Caplan

Reputation: 64

How do I change layout view on the application when i have multiple separate layouts(screens)?

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)>

Upvotes: 0

Views: 96

Answers (1)

braop
braop

Reputation: 196

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:

  1. 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.
  2. 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.

Upvotes: 1

Related Questions