기타/AOS, Kotlin

앱 개발 프로젝트에서 배운 점(4) : 프래그먼트 간의 데이터 전달

kyxxn 2023. 8. 15. 00:55
728x90

이번 프로젝트에서 제일로 어려웠던 부분이다.

 

상황은 이렇다.

  1. 메인 액티비티 레이아웃에 가이드라인 8 : 2로 LinearLayout 8, Start 이미지 2로 잡았다.
  2. LinearLayout에는 weightSum=10으로 하여 텍스트뷰 0.5, 프래그먼트_1_1은 7, 프래그먼트_2_1은 2.5 이렇게 weight를 주어 레이아웃을 형성했다.
  3. 메인 액티비티는 시작화면이다. 1_1과 2_1 프래그먼트에서 값을 설정한 뒤, Start 버튼을 눌렀을 때 이 데이터들이 1_2와 2_2 프래그먼트로 이동해야 한다.
  4. Start.setOnClick 리스너를 사용하면 정보 전달이 쉽게 가능하나, 이미 Start 온클릭 리스너는 프래그먼트의 변경하는 역할을 메인 액티비티에서 하고 있음.
  5. 데이터 전달까지 Start 이미지가 하게 되면, 두 메소드가 충돌을 함.

즉, 1_1과 2_1 프래그먼트에서 1_2와 2_2 프래그먼트로 데이터를 이동시켜주어야 한다.

수 많은 방법으로 이 문제를 해결하려 했다.

  • 프래그먼트에서 프래그먼트로
    장점 
    1. 간단하고 직관적임.
    2. 다이렉트로 주고받기 가능. 중간 과정을 거치지 않음
    단점
    1. 프래그먼트는 재사용성이 장점인데, 프래그먼트 간의 직접적인 의존성이 생겨버려서 유지보수와 코드 재사용성이 어려워짐.
    2. 생명주기를 굉장히 세밀하게 파고들어야 함.
  • 프래그먼트 → 메인 액티비티 → 프래그먼트
    장점 
    1. 프래그먼트 간의 직접적인 의존성 감소
    2. 프래그먼트의 재사용성 증가. (동일한 액티비티에 여러 프래그먼트를 포함 시킬 때 유용함)
    단점
    1. 중간 과정이 생기므로 코드의 복잡성 올라감
    2. 데이터 전달 과정에서 Bundle 사용 시, 정적 데이터만 전송이 가능해져 제약 발생 가능성
  • ViewModel 사용
    장점
    1. 뷰모델의 생명주기와 UI의 생명주기는 독립적임. 화면 회전 및 전환에도 데이터가 유지가 됨
    2. 프래그먼트 간의 의존성도 줄어듬
    3. LiveData와 함께 사용 시에 데이터 변경을 관찰하고, UI를 자동 업데이트 하는 게 가능.
    단점
    1. 초기 설정과 학습 곡선이 어려움
    2. 많이 사용 시 앱의 구조를 복잡하게 만듬

위 3가지 모두 사용해보았으나,

 

1번의 경우 너무 간단한 로직이 나올 수 있을 거 같아 공부에 효과가 없으리라 생각되어 탈락

3번의 경우 배우지 못한 개념으로 실전에서 잘못 사용했다간 코드가 매우 복잡해져서 탈락

그래서 2번으로 택하여 메인 액티비티에서 Bundle을 통해 데이터를 전달해주었다.

Bundle = 키와 밸류로 구성.

프래그먼트 → 메인 액티비티 → 프래그먼트

이 방법을 하기 위해서는 각각의 프래그먼트에서 싱글턴 객체 느낌으로, 전역에서 쓰일 수 있어야 한다.

위 코드는 메인 코틀린 파일의 Start 클릭 리스너이다.

프래그먼트의 전역 객체를 받아와서, 그 객체가 갖고있는 getData 메소드를 받아와서

데이터 클래스를 받아오는 상황이다.

 

그렇기에 각 프래그먼트에서는 전역객체로 아래와 같이 만들어두었다.

companion object에서 객체를 만들어 전역으로 선언하고, 다른 곳에서 쓸 수 있게 한다.

그리고 프래그먼트가 종료될 때 null로 하여 메모리 누수를 방지한다.

마지막으로 세터 메소드를 만들어서 bundle에 정보를 담고, 프래그먼트 객체에 넣어서 프래그먼트 생성을 한다.

그러고 다른 프래그먼트가 열릴 때, onCreate함수에서 Key값을 받아서 초기화한다.