아래 코드는 뷰 레이아웃에 배치한 2개의 EditText 컴포넌트를 핸들링하기 위해서 findViewById 함수를 통해서 컨트롤뷰를 구하는 방식의 코드야.
LoginFragment.kt
...
val editEmail = v.findViewById<EditText>(R.id.editEmail)
val editPassword = v.findViewById<EditText>(R.id.editPassword)
val loginService = retrofit.create(DiaryService::class.java)
val request = RequestLoginBody(editEmail.text.toString(), editPassword.text.toString())
...
위 코드는 아래와 같이 작성할 수도 있어.
LoginFragment.kt
...
val editEmail: EditText = v.findViewById(R.id.editEmail)
val editPassword: EditText = v.findViewById(R.id.editPassword)
val loginService = retrofit.create(DiaryService::class.java)
val request = RequestLoginBody(editEmail.text.toString(), editPassword.text.toString())
...
어쨌거나 findViewById 라는 함수를 사용해서 UI 레이아웃에 배치되어 있는 특정 리소스ID의 컨트롤을 뷰 변수에 할당하고 있어.
이번 포스트에서 알아볼 내용은 findViewById 함수를 사용하지 않고, 리소스ID 를 직접 이용할 수 있도록 뷰 바인딩을 하는 방법이야.
뷰 바인딩을 하면 뷰 레이아웃에 정의되어 있는 리소스ID를 직접 핸들링할 수 있게 되는거지.
위 코드가 뷰 바인딩을 사용했을 때 어떤 모습으로 바뀌는지를 먼저 살펴볼께.
val request = RequestLoginBody(binding.editEmail.text.toString(), binding.editPassword.text.toString())
보다시피 findViewById 사용코드는 모두 제거가 되었어. 대신 binding 이라는 객체의 멤버로 컨트롤 ID 를 직접 사용하는 방식으로 변경되었지.
그러면 위와 같이 사용하기 위해서 추가해주어야 할 코드를 살펴볼께.
가장 먼저 build.gradle.kts 파일에 뷰바인딩을 사용하도록 옵션을 설정해 주어야 해.
build.gradle.kts
...
android {
namespace = "com.woohahaapps.androiddiary"
compileSdk = 34
...
buildFeatures {
viewBinding = true
}
}
...
위 코드를 추가한 다음에는 Sync Now 를 해주어야 하지.
뷰바인딩을 사용할 클래스가 액티비티 클래스인지 프래그먼트 클래스인지에 따라 조금 다르게 코드가 작성되는데, 우선 프래그먼트 클래스에 코드를 추가하는 방법을 살펴볼께.
LoginFragment.kt
...
class LoginFragment : Fragment() {
private lateinit var mainActivity: MainActivity
private var _binding: FragmentLoginBinding? = null
private val binding get() = _binding!!
...
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
// Inflate the layout for this fragment
//val v: View = inflater.inflate(R.layout.fragment_login, container, false)
_binding = FragmentLoginBinding.inflate(inflater, container, false)
val v: View = binding.root
...
}
override fun onDestroyView() {
super.onDestroyView()
_binding = null
}
...
}
위 코드에서 FragmentLoginBinding 이라는 클래스는 앞서 build.gradle.kts 에 추가한 viewBinding = true 를 통해서 자동으로 생성되는 ViewBinding 클래스를 상속받는 클래스야.
프래그먼트 클래스의 이름 규칙을 따라 생성되는 클래스명이니 잘 봐둬.
프래그먼트에서는 binding 이라는 프로퍼티를 정의해서 사용하도록 코딩을 해주고 있어.
그럼 이번에는 액티비티 클래스에서 뷰 바인딩을 구현하는 방법을 살펴볼께.
MainActivity.kt
...
class MainActivity : AppCompatActivity() {
...
private lateinit var binding: ActivityMainBinding
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = ActivityMainBinding.inflate(layoutInflater)
preferences = PreferenceUtil(this)
enableEdgeToEdge()
//setContentView(R.layout.activity_main)
setContentView(binding.root)
//ViewCompat.setOnApplyWindowInsetsListener(findViewById(R.id.main)) { v, insets ->
ViewCompat.setOnApplyWindowInsetsListener(binding.main) {v, insets ->
val systemBars = insets.getInsets(WindowInsetsCompat.Type.systemBars())
v.setPadding(systemBars.left, systemBars.top, systemBars.right, systemBars.bottom)
insets
}
...