프래그먼트 전환을 할 때, 클릭한 앨범 정보를 다른 프래그먼트로 넘겨서 보여줘야 했다.
사진까지 넘겨주고 싶었는데, 어떤 사진이 있을지 모르니까 리소스를 넘겨주는 것보다는 이미지뷰의 이미지를 직접 넘겨주는 방법을 찾아보게 됐다.
// 앨범 클릭 시 정보 넘기기
private fun moveToAlbumFragment() {
val albumFragment = AlbumFragment()
val bundle = Bundle()
// 이미지뷰의 이미지를 비트맵으로 변환
val bitmap = (binding.homeAlbum1CoverIv.drawable as BitmapDrawable).bitmap
// 비트맵을 ByteArray로 직렬화
val byteArrayOutputStream = ByteArrayOutputStream()
bitmap.compress(Bitmap.CompressFormat.PNG, 100, byteArrayOutputStream)
val byteArray = byteArrayOutputStream.toByteArray()
// bundle에 데이터 담기
bundle.putByteArray("img", byteArray)
bundle.putString("title", binding.homeAlbum1TitleTv.text.toString())
bundle.putString("singer", binding.homeAlbum1SingerTv.text.toString())
// albumFragment의 arguments에 데이터를 담은 bundle을 넘겨줌
albumFragment.arguments = bundle
(context as MainActivity).supportFragmentManager.beginTransaction().replace(R.id.main_frm, albumFragment).commitAllowingStateLoss()
}
private fun receiveHomeData() {
// 번들로부터 ByteArray 받아오기
val byteArray = arguments?.getByteArray("img")
if (byteArray != null) {
// ByteArray를 Bitmap으로 변환
val bitmap = BitmapFactory.decodeByteArray(byteArray, 0, byteArray.size)
// 앨범 커버 이미지에 Bitmap 설정
binding.albumCoverImgIv.setImageBitmap(bitmap)
}
// 앨범 제목, 가수 설정
binding.albumTitleTv.text = arguments?.getString("title")
binding.albumSingerTv.text = arguments?.getString("singer")
}
어쨌든 성공은 했고, 나는 이미지 리소스를 직접 넘기는 게 아니라 ImageView의 이미지 자체를 넘기고 싶었던 거라 이미지를 번들에 byteArray 형태로 넘기는 게 최선이었다고 생각함. 하지만 ImageView에 설정된 이미지 자체를 번들로 직접 넘기는 것은 용량으로 인한 성능 저하의 우려 때문에 권장되지 않는다고 한다.
내가 쓴 방법 말고도, 번들로 이미지의 식별자나 경로 등을 넘기고, 필요한 경우 받는 측에서 해당 식별자나 경로를 사용하여 이미지를 설정하는 방법이 있다.
drawable id로 넘기는 방법
- 보내는 쪽 (HomeFragment.kt)
bundle.putInt("img", R.drawable.img_album_exp2)
- 받는 쪽 (AlbumFragment.kt)
arguments?.getInt("img")?.let { binding.albumCoverImgIv.setImageResource(it) }
코드가 훨씬 더 간단하지만, 리소스를 지정해서 넘겨줘야한다.
그렇지만 생각해보니 코틀린 파일에서 데이터에 직접 리소스를 넣어주는 경우라면 그 데이터에 들어간 리소스를 넘겨줘도 될 듯..? (어차피 서버에서 받아오는 순간 url을 넘겨주겠지만..) 순간 뭔가 잘못 생각해서 삽질했던 거 같은데 어쨌든 지식 +1이 된 것에 만족한다.