Как мне изменить вид макета в приложении, когда у меня есть несколько отдельных макетов (экранов)?

#java #android #android-layout

#java #Android #android-layout

Вопрос:

экран основной активности xml 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> 
  

найденный XML-экран 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>
  

основная деятельность 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";
}
}

  

математическая часть кода работала нормально — любые улучшения приветствуются. — как мне устранить ошибки, чтобы, когда я нахожу число, когда случайное число = текущее число и когда я нажимаю «Проверить», я хочу, чтобы оно привело меня ко второму экрану / макету (foundnum.xml ) — foundnum.xml
ошибка, которую я получаю от этого, заключается в следующем:

 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:

Исключение, которое вы получаете, заключается в том, что вы: Не можете добавить нулевое дочернее представление в ViewGroup.

ViewGroup — это представление, которое может содержать другие представления. ViewGroup является базовым классом для макетов в Android, таких как LinearLayout , RelativeLayout , FrameLayout и т. Д. Другими словами, ViewGroup обычно используется для определения макета, в котором представления (виджеты) будут установлены / упорядочены / перечислены на экране Android.

У вас есть две группы просмотра: одна activity_main.xml и foundnum.xml

В вашем коде (MainActivity) вы устанавливаете activity_main.xml как ваша ViewGroup с помощью этой строки кода setContentView(R.layout.activity_main); в вашем методе oncreate.

Что вызывает ошибку??Ошибка вызвана действием (установка текста или установка действия onclick) на tvfoundnum и buttonrestart1:

  • TextView tvfoundnum= findViewById(R.id.tvfound)
  • buttonrestart1 = (Button)findViewById(R.id.buttonrestart1);

Любое действие, которое вы им задаете, приведет к ошибке, поскольку эти представления не являются частью заданной группы просмотра. В других случаях они не содержатся в activity_main.xml и они еще не известны

Варианты решения: есть 2 способа добиться желаемого:

  1. Скрывая и отображая только те виды, которые вы хотите отобразить: это означает, что вам придется комбинировать foundnum.xml код для activity_main.xml . Таким образом, у вас есть один макет.
  2. С помощью фрагментов. С помощью фрагментов вы можете заставить один фрагмент управлять более чем одной группой просмотра (макетами).

Поскольку вы используете activity, я продемонстрирую вариант решения (1) ниже

Вариант решения один.Это новый макет (он содержит код из activity_main.xml amp; 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> 
  

Обратите внимание, что при запуске приложения обратите внимание, что некоторые виды скрыты, то есть

 <RelativeLayout>

   <!--page relative layout-->  This is visible (visibilty = visible )
   <!--grats relative layout-->  This is invisible (visibility = gone)
    
</RelativeLayout>
  

Выполнив все, что вы хотите сделать (проверив, есть ли число в счетчике …..), установите visible для <!--grats relative layout--> и установите visibility для <!--page relative layout-->

Вам нужно изменить оператор if в этой функции: changepage() на что-то вроде этого

 public void changepage(){

        if (myC.ccheck() == "equal"){
            page.setVisibility(View.GONE);
            grats.setVisibility(View.VISIBLE);
        }
        else{
            grats.setVisibility(View.GONE);
            page.setVisibility(View.VISIBLE);

        }
    }
  

Надеюсь, вы найдете это полезным. Если у вас есть проблемы, пожалуйста, прокомментируйте, я вам помогу.

Комментарии:

1. Привет, большое спасибо за помощь. Я проверил ваше решение, и оно сработало. Спасибо

2. эта функция, которую, по вашим словам, вы создали для возврата назад, как она выглядит ?.

3. что вы имеете в виду?