【はじめてのKotlinプログラミング(12)】Replayボタンで初期状態に戻す(intentとfinish)

前回
プラスボタンを押して、スコアが5になるとゲームクリアになる
簡単なスコアアプリをつくりました。

今回はその続きです。
リプレイボタンを押すと、初期状態に戻って(onCreateの再読み込み)
もう一度最初からプレイできるようにしてみましょう。

結論から言うと、今回使うのはintentとfinish()なので、
過去の動画の復習と、ちょっとだけ応用になります。それでは始めていきましょう

動画

コード

▼activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout 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">

    <TextView
        android:id="@+id/tvCount"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="24dp"
        android:layout_marginEnd="24dp"
        android:layout_marginRight="24dp"
        android:text="0問正解"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <TextView
        android:id="@+id/tvQuestion"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="24dp"
        android:text="番号順にタッチせよ"
        android:textSize="24sp"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/tvCount" />

    <Button
        android:id="@+id/btn0"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginTop="90dp"
        android:text="Button"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/tvQuestion" />

    <Button
        android:id="@+id/btn1"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginTop="32dp"
        android:text="Button"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/btn0" />

    <Button
        android:id="@+id/btn2"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginTop="32dp"
        android:text="Button"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/btn1" />

    <Button
        android:id="@+id/btn3"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginTop="32dp"
        android:text="Button"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/btn2" />
</androidx.constraintlayout.widget.ConstraintLayout>

▼MainActivity.kt

package com.example.fivescoreapp

import android.content.Intent
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.widget.Button
import android.widget.TextView

class MainActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        val tvScore:TextView =findViewById(R.id.tvScore)
        val btnMinus:Button =findViewById(R.id.btnMinus)
        val btnPlus:Button =findViewById(R.id.btnPlus)
        var num = 0

        //1)+ボタンを押したら、スコアが1増える
        btnPlus.setOnClickListener {
            num++

            //3)スコア(num)が5になったらGameClear
            if(num==5){
                val intent = Intent(this,GameClear::class.java)
                startActivity(intent)
                finish()
            }else{
                //1)プラスしたスコアをテキストに表示
                tvScore.text = num.toString()
            }
        }

        //2)-ボタンを押したら、スコアが1減る
        btnMinus.setOnClickListener {
            num--

            //4)スコア(num)が-5になったらGameOver
            if(num==-5){
                val intent = Intent(this,GameOver::class.java)
                startActivity(intent)
                finish()
            }else{
                //1)マイナスしたスコアをテキストに表示
                tvScore.text = num.toString()
            }
        }

    }
}

▼activity_game_clear.xml

&amp;lt;?xml version="1.0" encoding="utf-8"?&amp;gt;
&amp;lt;androidx.constraintlayout.widget.ConstraintLayout 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"
    android:background="#FFEB3B"
    tools:context=".GameClear"&amp;gt;

    &amp;lt;TextView
        android:id="@+id/textView"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="GameClear"
        android:textSize="34sp"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" /&amp;gt;

    &amp;lt;Button
        android:id="@+id/btnReplay"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="replay"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent" /&amp;gt;
&amp;lt;/androidx.constraintlayout.widget.ConstraintLayout&amp;gt;

▼GameClear.kt

package com.example.fivescoreapp

import android.content.Intent
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.widget.Button

class GameClear : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_game_clear)

        val btnReplay:Button =findViewById(R.id.btnReplay)

        //5)ボタンを押したらアクティビティを終了
        //5)'ボタンを押したらメインに渡す&自アクティビティを終了
        btnReplay.setOnClickListener {
            val intent =Intent(this,MainActivity::class.java)
            startActivity(intent)
            finish()
        }
    }
}

▼activity_game_over.xml

&amp;lt;?xml version="1.0" encoding="utf-8"?&amp;gt;
&amp;lt;androidx.constraintlayout.widget.ConstraintLayout 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"
    android:background="#87858A"
    tools:context=".GameOver"&amp;gt;

    &amp;lt;TextView
        android:id="@+id/textView2"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="GameOver"
        android:textSize="34sp"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" /&amp;gt;

    &amp;lt;Button
        android:id="@+id/btnReplay"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="replay"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent" /&amp;gt;
&amp;lt;/androidx.constraintlayout.widget.ConstraintLayout&amp;gt;

▼GameOver.kt

package com.example.fivescoreapp

import android.content.Intent
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.widget.Button

class GameOver : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_game_over)

        val btnReplay:Button=findViewById(R.id.btnReplay)

        //6)ボタンを押したらメインに渡す&自アクティビティを終了
        btnReplay.setOnClickListener {
            val intent = Intent(this,MainActivity::class.java)
            startActivity(intent)
            finish()
        }
    }
}

テキスト

1)finish()でアクティビティを終了してみる

それでは始めていきましょう。
第7回の動画で、intentで渡した後に
finish()で、アクティビティを終了する、というのを解説しました。
ひとまず復習がてら、finish()でアクティビティを終了してみましょう。

と、その前に、ゲームクリア、ゲームオーバーともに
リプレイボタンだけ、とりあえず設置しておきます。

ゲームクリアのxmlを開いてください。
ボタンを追加して、左右は中央で、
上下は一番下でいいと思います。
テキストはreplayとかにしてあげて
idは、ボタンのリプレイという意味で
btnReplay
これでOKとしましょう。

ゲームオーバーも同じことをすればいいので
ゲームオーバーxmlを開いて
ボタンを追加
左右は中央
上下は一番した、
テキストはreplay
idもさっきと同じでいいので
btnReplay
とかにしておきます。

これでレイアウトができたので
まずクリア画面でリプレイボタンが押されたらfinishしてみましょう。

*****************************
▼finish()でアクティビティを終了してみる

それでは、ゲームクリアktで、リプレイボタンを押したら自身のアクティビティを終了するように
finish()を記述してみます。
GameClear_ktを開いてください。

まずviewを取得して
val btnReplay :Button = findViewById(R.id.btnReplay)

//5)ボタンを押したらアクティビティを終了
btnReplay.setOnClickListener {
finish()
}

ひとまずこれで、エミュレータを起動して確認してみましょう。

はい、こんな感じで、元には戻ったのですが
プレイ画面の途中ですよね。

解決の説明の前に、これは何故こうなるかという
intentの仕組みについて解説します。

*****************************

2.intentとfinishの仕組みについて

解決法の説明の前に、intentとfinishの仕組みについて解説します。

ザックリ言うと

●intentは、呼び出し元の上に画面を重ねる作業

●finish()は、該当の画面を外に出す作業

になります。

てことで、

[1]MainActivityは、intentの後にfinish()

[2]Replayボタンを押したら、intentでMainActivityを新たに呼び出す

これが一番シンプルに、初期状態に戻すやり方です。

3.GameClearでReplayボタンを設置しよう

はい、それでは実際に作業していきましょう。

やることは2つです。

—————————–
①メインアクティビティで、次の画面にintentで渡したら、自身は終了させたいのでfinishさせる。
②リプレイボタンは、ただアクティビティを終了させるんじゃなくメインに渡して、終了する。

—————————–

てことでMainActivityはこう(finish()を追加)

//3)スコア(num)が5になったらGameClear
            if(num==5){
                val intent = Intent(this,GameClear::class.java)
                startActivity(intent)
                finish()

でGameClear画面はこう(intentを追加)

        //5)ボタンを押したらアクティビティを終了
        //5)'ボタンを押したらメインに渡す&自アクティビティを終了
        val btnReplay :Button = findViewById(R.id.btnReplay)

        btnReplay.setOnClickListener {
            val intent = Intent(this,MainActivity::class.java)
            startActivity(intent)
            finish()

4.GameOver画面も同じようにやったら終了

    コメントを残す