인텐트를 통하여 MainActivity에서 SubActivity를 불러와 데이터를 받는 간단한 투두 앱을 만들어 보았다.
파일 형식은 위와 같이 구성하였고,2022-Do it! 깡샘의 안드로이드 앱 프로그래밍 with 코틀린 저서와 링크에 공유된 실습코드에서 레이아웃 및 todo.jpg 리소스를 활용하였다.
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
android:id="@+id/item_root"
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:padding="16dp"
android:layout_margin="8dp">
<ImageView
android:id="@+id/item_icon"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/todo"/>
<TextView
android:id="@+id/item_data"
android:layout_width="0dp"
android:layout_weight="1"
android:layout_height="wrap_content"
android:textStyle="bold"
android:textSize="16dp"
android:layout_marginLeft="24dp"
/>
</LinearLayout>
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 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:orientation="vertical"
android:padding="24dp">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Todo 등록"
android:textSize="15dp"
android:textColor="@android:color/darker_gray"/>
<EditText
android:id="@+id/add_editView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:inputType="text"/>
</LinearLayout>
<?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">
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/main_recyclerView"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<com.google.android.material.floatingactionbutton.ExtendedFloatingActionButton
android:id="@+id/main_fab"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:layout_alignParentBottom="true"
android:layout_marginStart="30dp"
android:layout_marginTop="30dp"
android:layout_marginEnd="30dp"
android:layout_marginBottom="30dp"
android:text="Add Todo"
app:icon="@android:drawable/ic_input_add" />
</RelativeLayout>
package com.example.coroutines
import android.content.Intent
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import androidx.activity.result.ActivityResultLauncher
import androidx.activity.result.contract.ActivityResultContracts
import androidx.recyclerview.widget.LinearLayoutManager
import kotlinx.android.synthetic.main.activity_main.*
var DataList = ArrayList<Data>()
class MainActivity : AppCompatActivity() {
//val sharedPref = getSharedPreferences("todo_data", Context.MODE_PRIVATE)
val requestLauncher : ActivityResultLauncher<Intent> = registerForActivityResult(
ActivityResultContracts.StartActivityForResult()){
val resultData = it.data?.getStringExtra("result")
println("result data is : " + resultData.toString())
DataList += Data(R.drawable.todo, resultData.toString())
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
main_recyclerView.layoutManager = LinearLayoutManager(this)
main_recyclerView.adapter=MyAdapter()
main_fab.setOnClickListener(){
val intent: Intent = Intent(this, AddActivity::class.java)
requestLauncher.launch(intent)
}
}
}
인텐트를 보내어 result로 데이터를 다시 받아오는 방법은 크게 startActivityForResult
와 ActivityResultLauncher
의 2가지 방식이 있는데, 더 권장되는 방법인 후자의 방식으로 인텐트를 구성하였다.
resultLauncher
변수를 정의한 방식대로 resultData를 내가 지정한 인텐트에서 받아올 수 있고, 받아온 데이터를 DataList
에 추가하였다.
main_fab
버튼에 클릭 리스너를 넣고 버튼이 눌렸을 때 intent를 생성하여 앞서 지정한 requestLancher에 따라서 intent로 연결된 AddActivity
를 불러온다.
형식은
val intent: Intent = Intent(this, AddActivity::class.java)
를 당분간 착실히 지킬 생각이다.
package com.example.ch13_activity
import android.app.Activity
import android.os.Bundle
import android.view.Menu
import android.view.MenuItem
import androidx.appcompat.app.AppCompatActivity
import com.example.ch13_activity.databinding.ActivityAddBinding
class AddActivity : AppCompatActivity() {
lateinit var binding: ActivityAddBinding
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding= ActivityAddBinding.inflate(layoutInflater)
setContentView(binding.root)
}
override fun onCreateOptionsMenu(menu: Menu?): Boolean {
menuInflater.inflate(R.menu.menu_add, menu)
return super.onCreateOptionsMenu(menu)
}
override fun onOptionsItemSelected(item: MenuItem): Boolean = when(item.itemId){
R.id.menu_add_save -> {
val intent = intent
intent.putExtra("result", binding.addEditView.text.toString())
setResult(Activity.RESULT_OK, intent)
finish()
true
}
else -> true
}
}
AddActivity에는 Activity_xml
뿐만 아니라 상단에 메뉴바에 해당하는 menu_xml
파일도 함께 화면에 보여진다. 메뉴 바를 상단에 위치하기 위한 함수는 onCreateOptionsMenu
이며 여기서 상단에 메뉴바를 inflate 해준다. 화면에 저장버튼 하나만 존재하지만 메뉴에 여러 아이템을 구성했을 때에는 when문을 통하여 아이템마다 다른 동작을 해줄 수도 있겠다.
여기서는 저장버튼 하나만 있으므로,
override fun onOptionsItemSelected(item: MenuItem): Boolean = when(item.itemId){
R.id.menu_add_save -> {
val intent = intent
intent.putExtra("result", binding.addEditView.text.toString())
setResult(Activity.RESULT_OK, intent)
finish()
true
}
else -> true
}
}
이와 같은 메뉴 선택 리스너를 사용하였다. intent로 editText에 작성한 값을 담아 setResult로 결과값을 보내고, finish()
로 AddActivity를 종료 시킨다.
package com.example.coroutines
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.recyclerview.widget.RecyclerView
import kotlinx.android.synthetic.main.item_recyclerview.view.*
class CustomViewHolder(v: View) : RecyclerView.ViewHolder(v){
val itemIcon = v.item_icon
val itemData = v.item_data
}
class Data(val profile: Int, val todo: String)
class MyAdapter : RecyclerView.Adapter<CustomViewHolder>(){
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): CustomViewHolder {
val cellForRow = LayoutInflater.from(parent.context).inflate(R.layout.item_recyclerview,parent,false)
return CustomViewHolder(cellForRow)
}
override fun onBindViewHolder(holder: CustomViewHolder, position: Int) {
holder.itemIcon.setImageResource(DataList[position].profile)
holder.itemData.text = DataList[position].todo
}
override fun getItemCount(): Int {
return DataList.size
}
}
MyAdapter.kt
파일에 해당하는 리사이클러뷰는 이전 포스트를 참고하여 만들었고, 하나 다른 점은 MainActivity.kt
에서
var DataList = ArrayList<Data>()
로 데이터 리스트를 널값으로 초기화 한 후 인텐트로 받은 Data값들을 넣어준 것이다.