안드로이드 : diary – 뷰 바인딩

아래 코드는 뷰 레이아웃에 배치한 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
        }
...

Leave a Comment