findViewById로 접근

class MainActivity : AppCompatActivity() {

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

        val btn1 : Button = findViewById(R.id.btn1)
        val btn2 : Button = findViewById(R.id.btn2)
        val btn3 : Button = findViewById(R.id.btn3)

        btn1.text = "abcd"
        btn2.text = "abcd"
        btn3.text = "abcd"

        secondBtn.text = "sadfasdfasdf"
        // 아래 코드는 정의되지 않은 secondBtn이라는 버튼에 접근하려고 하므로 오류가 발생합니다.
        // secondBtn.text = "sadfasdfasdf"


    }

이와 같이 'findViewById'를 사용하여 뷰에 접근할 수 있습니다. 하지만 이 방법은 실행 시 모든 뷰 계층을 순회하여 해당 ID를 가진 뷰를 찾기 때문에 복잡한 뷰 계층 구조에서는 시간이 오래 걸릴 수 있습니다. 또한 다른 레이아웃 파일에서 같은 ID를 사용하는 경우, 의도하지 않은 뷰에 접근할 위험도 있습니다. 이런 이유로 현재는 'findViewById' 대신 View Binding이나 Data Binding과 같은 방법을 사용하는 것을 권장하고 있습니다.

ViewBinding으로 접근

ViewBinding을 사용하려면 먼저 앱 레벨의 build.gradle에서 아래와 같이 선언합니다.

buildFeatures{
		viewBinding = true
}

그런 다음, 아래와 같이 MainActivity에서 사용할 수 있습니다.

class MainActivity : AppCompatActivity() {

    private lateinit var binding : ActivityMainBinding

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        binding = ActivityMainBinding.inflate(layoutInflater)
		setContentView(binding.root)

        binding.testText.text= "이거는 변경된 텍스트"
        binding.testText.setOnClickListener{
val intent = Intent(this, SecondActivity::class.java)
            startActivity(intent)
}

}
}

RecyclerView의 Adapter에서는 아래와 같이 사용합니다.

class CustomViewAdapter(private val dataSet : ArrayList<String>) : RecyclerView.Adapter<CustomViewAdapter.ViewHolder>(){

    class ViewHolder(binding : TextRowItemBinding) : RecyclerView.ViewHolder(binding.root) {

        val myText : TextView = binding.myText
    }

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {

        val view = TextRowItemBinding.inflate(LayoutInflater.from(parent.context), parent, false)

        return ViewHolder(view)
    }

    override fun onBindViewHolder(holder: ViewHolder, position: Int) {

        holder.myText.text= dataSet[position]

    }

    override fun getItemCount(): Int {

        return dataSet.size

    }
}

ViewBinding의 장점은 뷰의 직접적인 참조를 제공하므로 null체크가 필요 없고, 각각의 XML 파일에 대한 바인딩 클래스가 생성되므로 클래스 변환 오류를 방지할 수 있습니다. 또한 성능도 뷰 계층을 순회하지 않으므로 findViewById보다 효율적이며, 가독성도 좋습니다.

DataBinding으로 접근

DataBinding을 사용하려면 먼저 앱 레벨의 build.gradle에서 아래와 같이 선언합니다.

buildFeatures{
		dataBinding = true
}

그런 다음, 아래와 같이 MainActivity에서 사용할 수 있습니다.

// DataBinding
// ViewBinding 이랑 뭐가 다른가?
// 이름처럼 데이터를 연결해주는 역할을 할 수 있습니다. (데이터와 같이 결합해서 사용할 수 있음)
// DataBinding + LiveData

class MainActivity : AppCompatActivity() {

    private lateinit var binding : ActivityMainBinding

    override fun onCreate(savedInstanceState: Bundle?) {

        super.onCreate(savedInstanceState)
        binding = DataBindingUtil.setContentView(this, R.layout.activity_main)

        binding.dataBindingEx.text= "바뀐 텍스트"
        binding.dataBindingEx.setOnClickListener{
val intent = Intent(this, SecondActivity::class.java)
            startActivity(intent)
}

}
}

데이터 바인딩을 사용하려면 레이아웃 XML 파일에 layout 태그를 사용하여 루트 뷰를 감싸야 합니다.
layout 태그를 사용하면 데이터 바인딩 라이브러리가 바인딩 클래스를 생성할 수 있습니다. 이 클래스를 통해 뷰와 데이터를 연결하고, 뷰에 직접 접근할 수 있게 됩니다.

<?xml version="1.0" encoding="utf-8"?>
<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">

    <data>
        <variable
            name="user"
            type="com.bokchi.jetpack_ex.Person" />
    </data>

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        tools:context=".MainActivity"
        android:orientation="vertical">

        <TextView
            android:textSize="100dp"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="@{user.age > 30 ? `나이 많음` : `나이 적음`}"
            />

        <Button
            android:text="btn"
            android:onClick="myClick"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"/>

    </LinearLayout>

</layout>

RecyclerView의 Adapter에서는 아래와 같이 사용합니다.

class CustomDataAdapter(private val dataSet : ArrayList<String>) : RecyclerView.Adapter<CustomDataAdapter.ViewHolder>(){

    class ViewHolder(binding : TextRowItemBinding) : RecyclerView.ViewHolder(binding.root) {

        val myText : TextView = binding.myText
    }

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {

        // val view = TextRowItemBinding.inflate(LayoutInflater.from(parent.context), parent, false)
        val view = DataBindingUtil.inflate<TextRowItemBinding>(LayoutInflater.from(parent.context), R.layout.text_row_item, parent,false)
        return ViewHolder(view)
    }

    override fun onBindViewHolder(holder: ViewHolder, position: Int) {

        holder.myText.text= dataSet[position]

    }

    override fun getItemCount(): Int {

        return dataSet.size

    }
}

DataBinding을 사용하면 UI와 데이터를 쉽게 연결할 수 있습니다. 뷰 바인딩과는 달리 레이아웃 파일 내에서 바로 데이터를 사용할 수도 있습니다.

DataBinding을 데이터와 연동해서 사용해보기

Person이라는 데이터 클래스를 만들고, 이를 UI와 연결하여 사용하면

data class Person (
    val name : String,
    val age : Int
)
<?xml version="1.0" encoding="utf-8"?>
<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">

    <data>
        <variable
            name="user"
            type="com.bokchi.jetpack_ex.Person" />
    </data>

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        tools:context=".MainActivity"
        android:orientation="vertical">

        <TextView
            android:id="@+id/test"
            android:textSize="100dp"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="@{user.name}"
            />

        <TextView
            android:textSize="100dp"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="@{Integer.toString(user.age)}"
            />

        <TextView
            android:textSize="100dp"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="@{user.age > 30 ? `나이 많음` : `나이 적음`}"
            />

        <Button
            android:text="btn"
            android:onClick="myClick"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"/>

    </LinearLayout>

</layout>

이렇게 사용하면 UI와 데이터를 연결하여 사용할 수 있습니다.

profile
나의 개발지식 output 공간

0개의 댓글