① data binding을 사용하기 위해 activity_song.xml 파일의 내용을 layout 컨테이너로 감싼다.
② SongActivity를 아래와 같이 수정한다.
class SongActivity : AppCompatActivity() {
lateinit var binding : ActivitySongBinding
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = ActivitySongBinding.inflate(layoutInflater)
setContentView(binding.root)
if(intent.hasExtra("title") && intent.hasExtra("singer")){
binding.songMusicTitleTv.text = intent.getStringExtra("title")
binding.songSingerNameTv.text = intent.getStringExtra("singer")
}
binding.songDownIb.setOnClickListener {
finish()
}
binding.songMiniplayerIv.setOnClickListener {
setPlayerStatus(true)
}
binding.songPauseIv.setOnClickListener {
setPlayerStatus(false)
}
}
fun setPlayerStatus (isPlaying : Boolean){
if(isPlaying){ // 재생중
binding.songMiniplayerIv.visibility = View.GONE
binding.songPauseIv.visibility = View.VISIBLE
} else { // 일시정지
binding.songMiniplayerIv.visibility = View.VISIBLE
binding.songPauseIv.visibility = View.GONE
}
}
}
코드를 실행시켜보자. 재생바를 눌렀을 때, 노래의 제목과 가수가 SongActivity에 나타나야 한다.
fragment_home.xml 파일의 home_album_img_iv1 이미지 뷰의 src 속성을 아래와 같이 변경한다.
android:src="@drawable/img_album_exp2"
HomeFragment의 라일락 이미지를 클릭했을 때 AlbumFragment로 이동해야 하며, 이 때 가수와 노래 제목에 대한 데이터가 전달되어야 한다. Fragment를 데이터 전달과 함께 전환하는 방법 중 몇가지만 소개해보도록 하겠다. (여기서, HomeFragment는 데이터를 전달하는 Fragment, AlbumFragment는 데이터를 전달받는 Fragment가 된다.)
별도의 의존성 없이도 사용할 수 있는 방법으로, 다소 오래된 방식임에도 불구하고 자주 사용된다.
① fragment_home.xml 파일에 "LILAC" 부분과 "아이유 (IU)" 부분의 TextView에 id를 매핑한다.
<TextView
android:id="@+id/title_lilac"
... />
<TextView
android:id="@+id/singer_iu"
... />
② HomeFragment의 homeAlbumImgIv1에 대한 클릭 이벤트 리스너를 아래와 같이 수정한다.
binding.homeAlbumImgIv1.setOnClickListener {
val bundle = Bundle()
bundle.putString("title", binding.titleLilac.text.toString())
bundle.putString("singer", binding.singerIu.text.toString())
val albumFragment = AlbumFragment()
albumFragment.arguments = bundle
(context as MainActivity)
.supportFragmentManager.beginTransaction()
.replace(R.id.main_frm, albumFragment).commitAllowingStateLoss()
}
③ AlbumFragment의 onCreateView 메서드에 아래의 내용을 추가한다.
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
binding = FragmentAlbumBinding.inflate(inflater,container,false)
binding.albumMusicTitleTv.text = arguments?.getString("title")
binding.albumSingerNameTv.text = arguments?.getString("singer")
binding.albumBackIv.setOnClickListener {
...
이제 코드를 실행시켜보자. AlbumFragment의 노래 제목과 가수명이 전달 받은 값으로 설정된 것을 확인할 수 있을 것이다.
① Moudule 수준의 build.gradle 파일에 아래의 의존성을 추가한다.
implementation("androidx.fragment:fragment-ktx:1.3.0")
② HomeFragment의 homeAlbumImgIv1에 대한 클릭 이벤트 리스너를 아래와 같이 수정한다.
binding.homeAlbumImgIv1.setOnClickListener {
setFragmentResult("TitleInfo", bundleOf("title" to binding.titleLilac.text.toString()))
setFragmentResult("SingerInfo", bundleOf("singer" to binding.singerIu.text.toString()))
(context as MainActivity)
.supportFragmentManager.beginTransaction()
.replace(R.id.main_frm, AlbumFragment()).commitAllowingStateLoss()
}
③ AlbumFragment의 onCreateView 메서드를 아래와 같이 수정한다.
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
binding = FragmentAlbumBinding.inflate(inflater,container,false)
setFragmentResultListener("TitleInfo") { requestKey, bundle ->
binding.albumMusicTitleTv.text = bundle.getString("title")
}
setFragmentResultListener("SingerInfo") { requestKey, bundle ->
binding.albumSingerNameTv.text = bundle.getString("singer")
}
binding.albumBackIv.setOnClickListener {
...
이외에도 다양한 방법이 있지만, 이번 포스팅에서는 위 두가지 방법에 대해서만 다루도록 하겠다.
이전 포스팅에서 MainActivity의 재생 바를 클릭해 SongActivity로 전환하는 방법을 알아보았다. 이번 포스팅에서는 SongActivity에서 다시 MainActivity로 돌아올 때, 데이터를 전달받는 방법을 알아보자.
① SongActivity의 onCreate 메서드를 아래와 같이 수정한다.
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = ActivitySongBinding.inflate(layoutInflater)
setContentView(binding.root)
var title : String? = null
var singer : String? = null
if(intent.hasExtra("title") && intent.hasExtra("singer")){
title = intent.getStringExtra("title")
singer = intent.getStringExtra("singer")
binding.songMusicTitleTv.text = title
binding.songSingerNameTv.text = singer
}
binding.songDownIb.setOnClickListener {
val intent = Intent(this, MainActivity::class.java)
intent.putExtra("message", title + " _ " + singer)
setResult(RESULT_OK, intent)
finish()
}
binding.songMiniplayerIv.setOnClickListener {
...
② MainActivity에 아래의 내용을 추가한다.
class MainActivity : AppCompatActivity() {
lateinit var binding : ActivityMainBinding
lateinit var activityResultLauncher: ActivityResultLauncher<Intent>
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = ActivityMainBinding.inflate(layoutInflater)
setContentView(binding.root)
initBottomNavigation()
val song = Song(binding.mainMiniplayerTitleTv.text.toString(), binding.mainMiniplayerSingerTv.text.toString())
activityResultLauncher = registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { result ->
if (result.resultCode == RESULT_OK) {
val data = result.data
if (data != null) {
val message = data.getStringExtra("message")
Log.d("message", message!!)
Toast.makeText(this, message, Toast.LENGTH_SHORT).show()
}
}
}
binding.mainPlayerCl.setOnClickListener {
val intent = Intent(this, SongActivity::class.java)
intent.putExtra("title", song.title)
intent.putExtra("singer",song.singer)
activityResultLauncher.launch(intent)
}
}
이제 코드를 실행시켜보자. SongActivity의 songDownIb를 클릭했을 때 HomeFragment로 전환되면서 노래 제목과 가수 이름이 토스트 메시지로 출력될 것이다.
이와 동일한 방법을 사용하여, Back 버튼을 클릭했을 때 토스트 메시지를 띄울 수도 있다. SongActivity에 아래의 메서드를 추가한다.
override fun onBackPressed() {
val intent = Intent(this, MainActivity::class.java)
intent.putExtra("message", "뒤로가기 버튼 클릭")
setResult(RESULT_OK, intent)
finish()
}
이제 뒤로가기 버튼을 클릭해도 토스트 메시지가 출력될 것이다.