onBackPressed

나고수·2022년 3월 6일
0

1일1공부

목록 보기
10/68
post-custom-banner

안드로이드의 back button기능을 내 맘대로 구현해 봅시다.

  • 액티비티에서 back button 구현
class MainActivity : AppCompatActivity() {

    private lateinit var callback: OnBackPressedCallback

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        onBackPressed()
    }

//activity에서는 이 함수를 override하고, 원하는 백버튼 이벤트를 구현하면 된다.
override fun onBackPressed() {
// 주석 처리된 부분 >> 원래 뒤로가기 버튼 기능이다. 
//지금은 주석처리 해놨으니까 뒤로가기가 안됨. 뒤로가기를 눌렀을 때 토스트가 나오도록 해놨음. 
// super.onBackPressed() 
Toast.makeText(this@MainActivity,"onBackPressed",Toast.LENGTH_SHORT).show()}
  • 프래그먼트에서 back button 구현
//fragment

 class MyFragment : Fragment() {

    private lateinit var callback: OnBackPressedCallback

    override fun onCreateView(
        inflater: LayoutInflater,
        container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {
        return inflater.inflate(R.layout.fragment_my, container, false)
    }

    override fun onAttach(context: Context) {
        super.onAttach(context)
        callback = object : OnBackPressedCallback(true) {
            override fun handleOnBackPressed() {
                //원하는 뒤로가기 기능을 구현해 줍니다. 
                Toast.makeText(requireActivity(), "onBackPressed", Toast.LENGTH_SHORT).show()
            }
        }
        //프래그먼트가 속한 액티비티에 onBackPressedDispatcher을 설정해줍니다. 
        requireActivity().onBackPressedDispatcher.addCallback(this, callback)
    }

    override fun onDetach() {
        super.onDetach()
        callback.remove()
    }
}
class MainActivity : AppCompatActivity() {

    private lateinit var callback: OnBackPressedCallback

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        val transaction = supportFragmentManager.beginTransaction()
        transaction.replace(R.id.fragment_container, MyFragment()).commit()
    }

    //fragment에 OnBackPressedCallback를 구현 한 다음 액티비티에서 onBackPressed()를 override해줘야 프래그먼트에서 설정한 백버튼 이벤트가 실행됩니다.
    override fun onBackPressed() {
        super.onBackPressed()
    }
}
  • 프래그먼트마다 다른 백버튼 이벤트를 주고 싶을 때 & viewPager에서 백버튼 이벤트
//보통 baseFragment를 만들어놓고, 다른 프래그먼트에 baseFragment를 상속받아 사용하는 경우가 많습니다.
open class MyFragment : Fragment() {

    private lateinit var callback: OnBackPressedCallback

    override fun onCreateView(
        inflater: LayoutInflater,
        container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {
        return inflater.inflate(R.layout.fragment_my, container, false)
    }

    override fun onAttach(context: Context) {
        super.onAttach(context)
        callback = object : OnBackPressedCallback(true) {
            override fun handleOnBackPressed() {
                when(this@MyFragment){
                //프래그먼트마다 다른 백버튼 이벤트를 설정합니다.
                    is Fragment1 -> {}
                    is Fragment2 -> {}
                    else -> {
                        //ex)여러 프래그먼트를 viewPager로 붙여서 viewPager 내에서 백 버튼 구현하고 싶은 경우
                        // viewPager로 붙인 프래그먼트들 사이에서는 기본적으로 백버튼이 작동되지 않는다
                        //f1 > (f2, f3, f4 이 하나의 뷰페이저라면), f3 > f2 이 되는게 아니라
                        //f3 > f1로 이동해 버린다.
                        //그래서 parentFragment가 뷰페이저 프래그먼트이면(여기서는 MyViewPager), 뷰페이저에서 구현한 백버튼 함수(보통 뷰페이저 첫 페이지면 뒷 프래그먼트로 , 첫페이지가 아니면 뷰페이저 내의 뒷페이지로 가라고 구현하겠지유)를 실행하라고 적어준다.
                        when(this@MyFragment.parentFragment){
                            is MyViewPager -> {(this@MyFragment.parentFragment as MyViewPager).back()}
                        }
                    }

                }
            }
        }
        //프래그먼트가 속한 액티비티에 onBackPressedDispatcher을 설정해줍니다.
        requireActivity().onBackPressedDispatcher.addCallback(this, callback)
    }

    override fun onDetach() {
        super.onDetach()
        callback.remove()
    }
}
//이런 식으로 baseFragment를 상속해서 사용하는 경우가 많음. 
class Fragment1 : MyFragment() {

    private lateinit var callback: OnBackPressedCallback

    override fun onCreateView(
        inflater: LayoutInflater,
        container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {
        return inflater.inflate(R.layout.fragment_my, container, false)
    }

}
class MyViewPager : MyFragment() {

    private lateinit var callback: OnBackPressedCallback

    override fun onCreateView(
        inflater: LayoutInflater,
        container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {
        return inflater.inflate(R.layout.fragment_my, container, false)
    }

    fun back() {
        //뷰페이저 내 첫번째 페이지면
        if (isFirstPage()) //뒤로가기구현 
        //뷰페이저 내 첫번째 페이지가 아니면 뷰페이저 내 에서 뒤로가기
        else binding.viewPager.currentItem = binding.viewPager.currentItem.minus(1)
    }

    fun isFirstPage() = binding.viewPager.currentItem == 0
}
profile
되고싶다
post-custom-banner

0개의 댓글