안드로이드 Intent, recycler view로 투두 리스트 구현

이영준·2022년 10월 3일
0

결과 및 파일 구성

인텐트를 통하여 MainActivity에서 SubActivity를 불러와 데이터를 받는 간단한 투두 앱을 만들어 보았다.

파일 형식은 위와 같이 구성하였고,

2022-Do it! 깡샘의 안드로이드 앱 프로그래밍 with 코틀린 저서와 링크에 공유된 실습코드에서 레이아웃 및 todo.jpg 리소스를 활용하였다.

xml 파일

item_recyclerview.xml

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

activity_add.xml

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

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

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

MainActivity.kt

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로 데이터를 다시 받아오는 방법은 크게 startActivityForResultActivityResultLauncher의 2가지 방식이 있는데, 더 권장되는 방법인 후자의 방식으로 인텐트를 구성하였다.

resultLauncher 변수를 정의한 방식대로 resultData를 내가 지정한 인텐트에서 받아올 수 있고, 받아온 데이터를 DataList에 추가하였다.

main_fab 버튼에 클릭 리스너를 넣고 버튼이 눌렸을 때 intent를 생성하여 앞서 지정한 requestLancher에 따라서 intent로 연결된 AddActivity를 불러온다.

형식은

val intent: Intent = Intent(this, AddActivity::class.java)

를 당분간 착실히 지킬 생각이다.

AddActivity.kt

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를 종료 시킨다.

MyAdapter.kt

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값들을 넣어준 것이다.

profile
컴퓨터와 교육 그사이 어딘가

0개의 댓글