본문 바로가기
Android

[Kotlin] 새로운 화면(Activity) 추가하고 데이터 주고받기

by bryan.oh 2023. 7. 23.
반응형

 

MainActivity 가 있을 때, 버튼을 눌러서 또 다른 Activity를 띄워보고

데이터를 전달하고, 두번째 엑티비티에서 변경한 결과도 받아오는 예제를 해보겠습니다.

안드로이드 스튜디오에서 새 프로젝트를 만들고,

EmptyActivity 를 선택 후 생성하면, 기존 화면(MainActivity)이 생성됩니다.

그리고 ViewBinding 으로 소스를 수정합니다. [Kotlin] findViewById 대신에 View binding 참고

 

새 화면(Activity) 생성

SecondActivity 를 만들어야겠죠.

MainActivity 와 같은 Package에서 우클릭 > New > Activity > Empty Activity

생성되는 경로는 달라도 상관없습니다

 

 

Activity정보를 입력하고 생성합니다.

 

자동으로 생성된 소스는 아래와 같습니다.

ViewBinding 으로 변경하겠습니다.

참고 : [Kotlin] findViewById 대신에 View binding

 

class SecondActivity : AppCompatActivity() {

    private lateinit var binding: ActivitySecondBinding
    
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        binding = ActivitySecondBinding.inflate(layoutInflater)
        val view = binding.root
        setContentView(view)
    }
}

 

첫번째 화면에서 TextInput 과 버튼을 생성합니다.

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

    <EditText
        android:id="@+id/main_title_textview"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginHorizontal="@dimen/app_hori_margin"
        android:text=""
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <Button
        android:id="@+id/main_test_button"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="send"
        android:layout_marginHorizontal="@dimen/app_hori_margin"
        app:layout_constraintBottom_toBottomOf="parent"
        />

</androidx.constraintlayout.widget.ConstraintLayout>

가운데에 입력할 수 있는 TextEditor 와 다음 화면으로 넘길 버튼이 있습니다.

버튼을 눌렀을 때 동작하는 이벤트를 생성합니다.

binding.mainTestButton.setOnClickListener{
    // do something
}

그리고 Intent 를 사용해서 Second Activity 를 실행합니다.

val intent = Intent(this, SecondActivity::class.java)
intent.putExtra("message", textString)
startActivity(intent)

참고 : Intent 에서 alt + Enter 키를 눌러서 Import 해줍니다.

위의 startActivity(intent) 는 MainActivity 에서 SecondActivity 로 데이터를 넘길 수 있지만,

결과를 받아올 수 없습니다.

우선 SecondActivity 에서 데이터를 받는 부분은 아래와 같습니다.

val message = intent.getStringExtra("message")
Log.d(tag, "SecondActivity receive : $message")

 

데이터 넘기고 결과 받기 ( ActivityResultLauncher )

startActivityForResult 는 deprecated 되었습니다.

우선 MainActivity 에 class property 를 생성합니다.

class MainActivity : AppCompatActivity(), View.OnClickListener {

    lateinit var secondActivityResultLauncher: ActivityResultLauncher<Intent>

    override fun onCreate(savedInstanceState: Bundle?) {
        ...

그리고 결과를 받았을 때의 코드를 onCreate 에서 선언합니다.

onCreate(), onStart() 만 가능.

MainActivity.kt 의 onCreate() 안에서

secondActivityResultLauncher = registerForActivityResult(ActivityResultContracts.StartActivityForResult()){
    if (it.resultCode == RESULT_OK) {
        val data: Intent? = it.data
        val message = data?.getStringExtra("resultMessage")
        Log.d(tag, "Received Result: $message")
    }
}
SecondActivity 에서 결과를 받았고 resultCode 는 OK 일 때, "resultMessage" 라는 key 로 string 을 받아옵니다.
"resultMessage" 는 SecondActivity 에서 정합니다.

 

그리고 startActivity() 가 아닌 launch 로 SecondActivity 를 호출합니다.

아래 코드는 버튼 클릭 안에 작성하면 됩니다. (전체코드는 글 하단에..)

val intent = Intent(this, SecondActivity::class.java)
intent.putExtra("message", "Hello~ Bryan~")
secondActivityResultLauncher.launch(intent)

 

SecondActivity.kt 에서 결과 리턴하기

var message = "Hi there~"
val resultIntent = Intent()
resultIntent.putExtra("resultMessage", "Result from SecondActivity : $message")
setResult(RESULT_OK, resultIntent)
this.finish()

Intent 를 생성하고, "resultMessage" 키에 메시지를 전달하고, Result code 를 등록하고, secondActivity 를 종료합니다.

 

그러면, MainActivity 의 아래 코드가 실행이 됩니다.

secondActivityResultLauncher = registerForActivityResult(ActivityResultContracts.StartActivityForResult()){
    if (it.resultCode == RESULT_OK) {
        val data: Intent? = it.data
        val message = data?.getStringExtra("resultMessage")
        Log.d(tag, "Received Result: $message")
    }
}

 

 

전체 소스

MainActivity.kt

package com.example.test01

import android.content.Intent
import android.os.Bundle
import android.util.Log
import android.view.View
import androidx.activity.result.ActivityResultLauncher
import androidx.activity.result.contract.ActivityResultContracts
import androidx.appcompat.app.AppCompatActivity
import com.example.test01.databinding.ActivityMainBinding

class MainActivity : AppCompatActivity(), View.OnClickListener {

    private val tag = "Main"
    private lateinit var binding: ActivityMainBinding
    lateinit var secondActivityResultLauncher: ActivityResultLauncher<Intent>

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        binding = ActivityMainBinding.inflate(layoutInflater)
        val view = binding.root
        setContentView(view)

        binding.mainTestButton.setOnClickListener(this)

        secondActivityResultLauncher = registerForActivityResult(ActivityResultContracts.StartActivityForResult()){
            // SecondActivity 로 부터 응답을 받음
            if (it.resultCode == RESULT_OK) {
                val data: Intent? = it.data
                val message = data?.getStringExtra("resultMessage")
                Log.d(tag, "Received Result: $message")
            }
        }
    }

    override fun onClick(v: View?){
        when(v?.id) {
            binding.mainTestButton.id -> {
                // SecondActivity 실행
                var textString = binding.mainTitleTextview.text.toString()
                val intent = Intent(this, SecondActivity::class.java)
                intent.putExtra("message", textString)
                secondActivityResultLauncher.launch(intent)
            }
            else -> {
                Log.d(tag, "view(" + v?.id + ")'s callback not found")
            }
        }
    }
}

SecondActivity.kt

package com.example.test01

import android.content.Intent
import android.os.Bundle
import android.util.Log
import androidx.appcompat.app.AppCompatActivity
import com.example.test01.databinding.ActivitySecondBinding

class SecondActivity : AppCompatActivity() {

    private val tag = "SecondActivity"
    private lateinit var binding: ActivitySecondBinding

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        binding = ActivitySecondBinding.inflate(layoutInflater)
        val view = binding.root
        setContentView(view)

        val message = intent.getStringExtra("message")
        Log.d(tag, "SecondActivity receive : $message")

        binding.secondFinishButton.setOnClickListener {
            val resultIntent = Intent()
            resultIntent.putExtra("resultMessage", "Hello Bryan! From.Second")
            setResult(RESULT_OK, resultIntent)
            this.finish()
        }
    }
}

 

 

 

728x90
반응형

댓글