액티비티와 프래그먼트에서 사용할 수 있는 메서드가 달라서 구현할 때 소스코드를 많이 찾아봤다.
Fragment 클래스는 context를 상속받지 않기 때문에 context 관련 메서드들을 사용할 수 없는 것이었다.
프래그먼트에서 this를 대신하는 방법은 다음 두 가지가 있다.
context를 Fragment에서 받을 수 있으면 사용할 수 있게 된다.
구현 방법은 다음과 같다.
Fragment 클래스의 생명주기 콜백 메서드인 onAttach()의 매개변수로 context를 받는다.
여기서 매개변수로 들어온 context를 프래그먼트를 띄운 액티비티로 형변환하여 사용하면 된다.
class ChatFragment : Fragment() {
// context를 할당할 변수
lateinit var mActivity: MainActivity
override fun onAttach(context: Context) { // context에 정의된 메서드(runOnUiThread 등)를 사용하기 위함
super.onAttach(context)
// context를 액티비티로 형변환해서 할당
mainActivity = context as MainActivity
}
.
.
.
}
Toast.makeText(requireContext(), "위치 서비스를 사용할 수 없습니다. 위치 권한을 설정해주세요.", Toast.LENGTH_LONG).show()
Context 에 정의된 메서드
Context를 파라미터(매개변수)로 받는 메서드
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
return inflater.inflate(R.layout.fragment_life, container, false)
}
override fun onStart() {
super.onStart()
// Button을 참조해서 클릭 리스너 달기
mainActivity.findViewById<Button>(R.id.buttonTest).setOnClickListener {
Toast.makeText(mainActivity, "플래그먼트에서도 Toast가 됩니다", Toast.LENGTH_LONG).show()
}
// TextView를 참조해서 텍스트 바꾸기
mainActivity.findViewById<TextView>(R.id.textViewTest).text = "처음"
// 스레드 돌리기
thread(start = true){
Thread.sleep(3000)
// 3초후에 runOnUiThread를 통해 TextView의 텍스트 바꾸기
mainActivity.runOnUiThread {
mainActivity.findViewById<TextView>(R.id.textViewTest).text = "3초후에 바뀌었네요"
}
}
}