[android] view 접근 방법

Pyo·2024년 7월 21일
0

지난번 안드로이드에서 뷰에 접근하는 방법으로 findViewById, dataBinding을 비교하여 정리를 해봤는데 이번에는 안드로이드에서 대표적으로 뷰에 접근하는 방법인 findViewById,Kotlin Android Extensions,DataBinding,ViewBinding을 비교하고 정리하는 글을 쓰려고 한다.

findViewById

가장 기본적이고 간단한 방법으로 View의 id값을 기반으로 Activity에서 View에 접근하는 방법이다. DataBinding,ViewBinding에 비해 비교적 간단하지만 타입 안전성 부족,코드의 중복,성능 문제등의 단점이 존재한다.

activity_find_view_by_id.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/main"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".access_view.FindViewByIdActivity"
    android:orientation="vertical">

    <Button
        android:id="@+id/findViewByIdBtn1"
        android:text="findViewByIdBtn1"
        android:layout_margin="10dp"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"/>

    <Button
        android:id="@+id/findViewByIdBtn2"
        android:text="findViewByIdBtn2"
        android:layout_margin="10dp"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"/>
    <Button
        android:id="@+id/findViewByIdBtn3"
        android:text="findViewByIdBtn3"
        android:layout_margin="10dp"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"/>

</LinearLayout>

FindViewByIdActivity

class FindViewByIdActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_find_view_by_id)

        findViewById<Button>(R.id.findViewByIdBtn1).text = "abcd"
        findViewById<Button>(R.id.findViewByIdBtn2).text = "abcd"
        findViewById<Button>(R.id.findViewByIdBtn3).text = "abcd"

    }
}

실행 결과

Kotlin Android Extensions

현재는 지원하지 않는 방식으로써 기존에는 findViewById없이 편리하게 뷰에 접근할 수 있도록 해주었지만
id로 구분하지 않기 때문에 다른 xml 파일의 뷰에 접근하게 될 경우 에러가 발생, 성능 저하등 여러가지 문제로 현재는 사용되지 않는다.

View Binding

findViewById,Kotlin Android Extensions 보다는 사용방법이 조금 복잡하지만 코드의 안전성과 생산성을 높이는 데 큰 도움이 된다. findViewById 방법과는 다르게 타입안전성,null안전성,성능 향상등 여러가지 장점이 있기 때문에 널리 사용되고 있는 방법이다.

View Binding은 Activity,Fragment에 따라서 사용되는 방법 다르기 때문에 각각 정리하도록 하겠다.

우선 View Binding을 사용할수 있도록 gradle에 추가한다.

Activity

activity_view_binding

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/main"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".access_view.ViewBindingActivity">

    <TextView
        android:id="@+id/viewBindingText"
        android:text="View Binding"
        android:textSize="50sp"
        android:textStyle="bold"
        android:textColor="@color/black"
        android:gravity="center"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />

</LinearLayout>

ViewBindingActivity

class ViewBindingActivity : AppCompatActivity() {

    private lateinit var binding : ActivityViewBindingBinding

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        binding = ActivityViewBindingBinding.inflate(layoutInflater)
        val view = binding.root
        setContentView(view)
        binding.viewBindingText.text = "Activity : View Binding 성공"

        binding.viewBindingText.setOnClickListener{
            startActivity(Intent(this,ViewBindingFragmentActivity::class.java))
        }

    }
}

Fragment

activity_view_binding_fragment.xml

<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/main"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".access_view.ViewBindingFragmentActivity">

    <FrameLayout
        android:id="@+id/frameArea"
        android:layout_width="match_parent"
        android:layout_height="match_parent"/>

</androidx.constraintlayout.widget.ConstraintLayout>

ViewBindingFragmentActivity

class ViewBindingFragmentActivity : AppCompatActivity() {

    val manager = supportFragmentManager
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_view_binding_fragment)

        val transaction = manager.beginTransaction()
        val fragment = ViewBindingFragment()
        transaction.replace(R.id.frameArea,fragment)
        transaction.addToBackStack(null)
        transaction.commit()

    }
}

fragment_view_binding.xml

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".access_view.ViewBindingFragment">

    <!-- TODO: Update blank fragment layout -->
    <TextView
        android:id="@+id/fragmentText"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:textSize="40sp"
        android:text="@string/hello_blank_fragment" />

</FrameLayout>

ViewBindingFragment

class ViewBindingFragment : Fragment() {

    private var _binding : FragmentViewBindingBinding? = null
    private val binding get() = _binding!!
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
    }

    override fun onCreateView(
        inflater: LayoutInflater, container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {

        _binding = FragmentViewBindingBinding.inflate(inflater,container,false)
        val view = binding.root

        binding.fragmentText.text = "Fragment : View Binding 성공"

        return view
    }
}

실행 결과

Data Binding

Data Binding 또한 findViewById,Kotlin Android Extensions 보다는 사용방법이 조금 복잡하지만 코드의 안전성과 생산성을 높이는 데 큰 도움이 된다. ViewBindig보다 설정이 다소 불편하며, 성능이 떨어질수 있지만, 양방향 바인딩 지원, MVVM 패턴과 잘 어울리며, 코드와 UI의 명확한 분리를 통해 가독성이 좋다.

Data Binding 또한 Activity,Fragment에 따라서 사용되는 방법 다르기 때문에 각각 정리하도록 하겠다.

우선 Data Binding을 사용할수 있도록 gradle에 추가한다.

Activity

activity_data_binding.xml

<layout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    >
    <androidx.constraintlayout.widget.ConstraintLayout
        android:id="@+id/main"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        tools:context=".access_view.DataBindingActivity">

        <TextView
            android:id="@+id/dataBindingText"
            android:text="Data Binding"
            android:textSize="50sp"
            android:textStyle="bold"
            android:textColor="@color/black"
            android:gravity="center"
            android:layout_width="match_parent"
            android:layout_height="match_parent" />
    </androidx.constraintlayout.widget.ConstraintLayout>
</layout>

DataBindingActivity

class DataBindingActivity : AppCompatActivity() {
    private lateinit var bindng : ActivityDataBindingBinding

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        bindng = DataBindingUtil.setContentView(this,R.layout.activity_data_binding)

        bindng.dataBindingText.text = "Activity : Data Binding 성공"

        bindng.dataBindingText.setOnClickListener{
            startActivity(Intent(this,DataBindingFragmentActivity::class.java))
        }
    }
}

Fragment

activity_data_binding_fragment.xml

	// viewBinding 과 같은 방식으로 프래그 먼트와 액티비티를 연결시켜준다.

DataBindingFragmentActivity

	// viewBinding 과 같은 방식으로 프래그 먼트와 액티비티를 연결시켜준다.

fragment_data_binding.xml

<?xml version="1.0" encoding="utf-8"?>
<layout>
    <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:tools="http://schemas.android.com/tools"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        tools:context=".access_view.DataBindingFragment">
        <!-- TODO: Update blank fragment layout -->
        <TextView
            android:id="@+id/fragmentText"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:textSize="40sp"
            android:text="@string/hello_blank_fragment" />
    </FrameLayout>
</layout>

DataBindingFragment

class DataBindingFragment : Fragment() {

    private  lateinit var  binding : FragmentDataBindingBinding

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
    }

    override fun onCreateView(
        inflater: LayoutInflater, container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {

        binding = DataBindingUtil.inflate(inflater,R.layout.fragment_data_binding,container,false)

        binding.fragmentText.text = "Fragment : Data Binding 성공"

        // Inflate the layout for this fragment
        return binding.root
    }

}

실행 결과

정리

findViewById,Kotlin Android Extensions,View Binding,Data Binding의 장단점과 사용방법에 대해 정리해보았다. 확실히 사용하기 편한것은 많은 단점,리스크가 존재 하는것 같다. 프로젝트의 요구사항,복잡성에따라서 사용하는 것이 좋을것 같고, 특히 데이터와 UI의 상호작용이 많은 경우 mvvm 패턴을 적극 사용할수 있는 데이터 바인딩 방법을 사용하는 것이 좋을것 같다.

0개의 댓글

관련 채용 정보