이 글은 이것이 안드로이드다 with 코틀린(개정판)를 참고하여 작성하였습니다.
작성자 : 임예람
개발환경은 Windows, Android Studio입니다.
1. (14-5) 화면 구성하기: 프래그먼트
📌프래그먼트: 액티비티 내에서 화면 UI의 일부이다. 여러 개의 프래그먼트를 조합해 액티비티가 출력하는 한 화면의 UI를 표현할 수 있으며 하나의 프래그먼트를 다른 액티비티에 재사용할 수 있다.
<프래그먼트 사용하기>
👉🏻 프래그먼트를 만들어 준다.
<resources>
<string name="app_name">Fragment</string>
<string name="title_list">List</string>
<string name="title_detail">Detail</string>
</resources>
✍🏻 strings.xml에 다음과 같이 코드를 적으면 각 name 값으로 id 값이 부여된다.
👉🏻 다음과 같이 프래그먼트를 만들어 준다.
👉🏻 팔레트에서 Fragments를 클릭하면 본인이 만든 프래그먼트 사용 가능하다.
✍🏻 위의 방법 대신 프레임 레이아웃을 사용하면 동작이 더욱 원활하다.
<프래그먼트 화면 전환하기>
package com.example.fragment
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import com.example.fragment.databinding.ActivityMainBinding
class MainActivity : AppCompatActivity() {
val binding by lazy { ActivityMainBinding.inflate(layoutInflater) }
val listFragment by lazy { ListFragment() }
val detailFragment by lazy { DetailFragment() }
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(binding.root)
setFragment()
}
//디테일 페이지로 이동
fun goDetail(){
val transaction = supportFragmentManager.beginTransaction()
transaction.add(R.id.frameLayout, detialFragment)
transaction.addToBackStack("detail")
transaction.commit()
}
//뒤로 이동
fun goBack() {
//뒤로 가기 명령어를 담고 있다.
onBackPressed()
}
fun setFragment() {
//1. 사용할 프래그먼트 생성
// val listFragment = ListFragment()
//2. 트랜잭션 생성
val transaction = supportFragmentManager.beginTransaction()
//3. 트랜잭션을 통해 프래그먼트 삽입
transaction.add(R.id.frameLayout, listFragment)
transaction.commit()
}
}
mainActivity.kt
package com.example.fragment
import android.content.Context
import android.os.Bundle
import androidx.fragment.app.Fragment
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import com.example.fragment.databinding.FragmentListBinding
//프래그먼트가 메인 액티비티에 삽입되는 순간 호출된다.
class ListFragment : Fragment() {
lateinit var binding: FragmentListBinding
//변수에 메인 액티비티 담아둠
lateinit var mainActivity: MainActivity
//나를 삽입한 액티비티 담김
override fun onAttach(context: Context) {
super.onAttach(context)
if(context is MainActivity) mainActivity = context
}
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
binding = FragmentListBinding.inflate(inflater, container, false)
return binding.root
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
//버튼 누르면 디테일 페이지로 이동하도록 한다.
binding.btnNext.setOnClickListener{
mainActivity.goDetail()
}
}
}
ListFragment.kt
package com.example.fragment
import android.content.Context
import android.os.Bundle
import androidx.fragment.app.Fragment
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import com.example.fragment.databinding.FragmentDetailBinding
import com.example.fragment.databinding.FragmentListBinding
class DetailFragment : Fragment() {
lateinit var binding: FragmentDetailBinding
lateinit var mainActivity: MainActivity
//나를 삽입한 액티비티 담김
override fun onAttach(context: Context) {
super.onAttach(context)
if(context is MainActivity) mainActivity = context
}
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
binding = FragmentDetailBinding.inflate(inflater, container, false)
return binding.root
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
//버튼 누르면 이전전 페이로 이동하도록 한다.
binding.btnNext.setOnClickListener{
mainActivity.goBack()
}
}
}
DetailFragment.kt
✍🏻 clickable:True: 뒤에 있는 프래그먼트가 클릭되지 않도록 한다.
<프래그먼트에 값 전달하기>
fun setFragment() {
val bundle = Bundle()
bundle.putString("key1", "List Fragment")
bundle.putInt("key2", 20210331)
listFragment.arguments = bundle
val transaction = supportFragmentManager.beginTransaction()
//3. 트랜잭션을 통해 프래그먼트 삽입
transaction.add(R.id.frameLayout, listFragment)
transaction.commit()
}
mainActivity.kt
👉🏻 setFragment에서 어떠한 값을 보낼지 설정한다.
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
with(binding){
arguments?.apply {
textTitle.text = getString("key1")
textValue.text = "${ getInt("key2") }"
}
//버튼 누르면 디테일 페이지로 이동하도록 한다.
btnNext.setOnClickListener{
mainActivity.goDetail()
}
}
}
ListFragment.kt
✍🏻 apply: 이 메소드를 사용하면 arguments가 this를 의미한다.
fun setValue(value: String){
binding.textFromActivity.text = value
}
👉🏻 값을 받아오는 함수 새로 생성한다.
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(binding.root)
setFragment()
//버튼을 누르면 값을 전달해서 표시한다.
binding.btnSend.setOnClickListener{
listFragment.setValue("값 전달하기")
}
}
👉🏻 send 버튼을 누르면 값이 이동하도록 이벤트 설정을 한다.
2. 14-5) 화면 구성하기: 프래그먼트끼리 값 주고 받기
📌 목표: Sender 프래그먼트에서 Receiver 프래그먼트로 값 주고 받기!
👉🏻 버튼을 2개 만들어 연결한다.
class ReceiverFragment : Fragment() {
lateinit var binding: FragmentReceiverBinding
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
binding = FragmentReceiverBinding.inflate(inflater, container, false)
return inflater.inflate(R.layout.fragment_receiver, container, false)
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
//키와 번들을 보내며 수신 준비 완료
setFragmentResultListener("request") { key, bundle ->
bundle.getString("senderKey")?.let{
binding.textiew.text = value
}
}
}
}
ReceiverFragment.kt
👉🏻 값을 받을 준비 끝
class SenderFragment : Fragment() {
lateinit var binding: FragmentSenderBinding
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
binding = FragmentSenderBinding.inflate(inflater, container, false)
return binding.root
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
with(binding) {
btnYes.setOnClickListener{
//"senderkey" 값에서 "Yes"값을 담겠다는 의미
//여기서 senderkey는 아까의 request
val bundle = bundleOf("senderkey" to "Yes")
setFragmentResult("request", bundle)
}
btnNo.setOnClickListener{
//"senderkey" 값에서 "Yes"값을 담겠다는 의미
val bundle = bundleOf("senderkey" to "No")
setFragmentResult("request", bundle)
}
}
}
}
SenderFragment.kt
👉🏻 값을 보내는 코드
'GDSC HUFS 3기 > Android with Kotlin Team 5' 카테고리의 다른 글
[5팀]코틀린 안드로이드 기초강의_41,42 | SQLite, Room (0) | 2021.11.23 |
---|---|
[5팀] 코틀린 안드로이드 기초강의_39~40 | 파일 입출력, SharedPrefere (0) | 2021.11.23 |
[5팀] 코틀린 안드로이드 기초강의_29~30 | 리사이클러뷰 (0) | 2021.11.03 |
[5팀] 코틀린 안드로이드 기초강의_27~28 | 액티비티 ,스피너(1) (0) | 2021.11.01 |
[5팀] 코틀린 안드로이드 기초강의_25~26 | 시크바, 레이팅바 (0) | 2021.10.29 |