Android View에 대한 접근

핑구·2022년 9월 24일
2

Adapter + ViewBinding + DataBinding

강의내용을 최대한 써보기 위해 아주 살짝 바꿔보았다.

이런식으로 메인에서 버튼을 눌러 각각의 Activity로 Intent되게 했다.
그리고 DataBinding은 EditText에 적은 내용을 버튼을 누르면 리스트에 들어가고 밑에 TextView에 띄우게 해보았다.

MainActivity.kt

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

        val array = ArrayList<String>()

        array.add("1번")
        array.add("2번")
        array.add("3번")
        array.add("4번")
        array.add("5번")
        array.add("6번")
        array.add("7번")
        array.add("8번")
        array.add("9번")
        array.add("10번")
        array.add("11번")
        array.add("12번")
        array.add("13번")
        array.add("14번")
        array.add("15번")
        array.add("16번")
        array.add("17번")
        array.add("18번")

        val customAdapter = CustomAdapter(array)

        val rv = findViewById<RecyclerView>(R.id.rv)
        rv.adapter= customAdapter
        rv.layoutManager= LinearLayoutManager(this)

        // Kotlin extensions
        goView.setOnClickListener {
            val intent = Intent(this, ViewBindingActivity::class.java)
            startActivity(intent)
        }

        goData.setOnClickListener {
            val intent = Intent(this, DataBindingActivity::class.java)
            startActivity(intent)
        }

    }
}

Kotlin extensions를 사용하여 버튼을 바로 사용해보았다.
유용해보이지만 해당 Activity가 아니면 null예외가 발생할 수 있고, 성능 이슈도 있어서 구글에서는 ViewBinding과 DataBinding을 추천한다고 한다.

CustomAdapter.kt

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

    class ViewHolder(view : View) : RecyclerView.ViewHolder(view) {

        val myText : TextView

        init {
            myText = view.findViewById(R.id.myText)
        }

    }

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

        val view = LayoutInflater.from(parent.context).inflate(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

    }
}

adapter는 모두 동일하다.

ViewBindingActivity.kt

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)

        val array = ArrayList<String>()

        array.add("1번")
        array.add("2번")
        array.add("3번")
        array.add("4번")
        array.add("5번")
        array.add("6번")
        array.add("7번")
        array.add("8번")
        array.add("9번")
        array.add("10번")
        array.add("11번")
        array.add("12번")
        array.add("13번")
        array.add("14번")
        array.add("15번")
        array.add("16번")
        array.add("17번")
        array.add("18번")

        val customAdapter = CustomViewAdapter(array)

        val rv = binding.rv
        rv.adapter= customAdapter
        rv.layoutManager= LinearLayoutManager(this)
    }
}

viewbinding은 binding을 선언해서 바로 레이아웃 id들에 접근이 가능하다.
databinding은 viewbinding과 다르게 데이터와 결합해서 사용할 수 있다.

DataBindingActivity.kt

class DataBindingActivity : AppCompatActivity() {

    private lateinit var binding : ActivityDataBindingBinding
    val array = ArrayList<String>()

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

        binding = DataBindingUtil.setContentView(this, R.layout.activity_data_binding)

    }
    fun myClick(view : View) {
        val input = Test(binding.edit.text.toString())
        binding.input= input

        array.add(binding.edit.text.toString())

        val customDataAdapter = CustomDataAdapter(array)

        val rv = binding.rv
        rv.adapter= customDataAdapter
        rv.layoutManager= LinearLayoutManager(this)

    }
}

위와 같이 myClick이라는 함수를 만들어 버튼에서 onclick을 이용해 바로 적용시켰다.
미리 만들어놓은 Test라는 data class를 사용하여 edit의 글자를 받아들여 적용시켰다.

activity_data_binding_xml

<?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="input"
            type="com.example.jetpackstudy.Test" />
    </data>

    <LinearLayout
        android:padding="10dp"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        tools:context=".DataBinding.DataBindingActivity"
        android:orientation="vertical">

        <LinearLayout
            android:layout_marginBottom="10dp"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="horizontal">
            <EditText
                android:id="@+id/edit"
                android:layout_width="0dp"
                android:layout_height="wrap_content"
                android:layout_weight="4"/>
            <Button
                android:onClick="myClick"
                android:layout_width="0dp"
                android:layout_height="wrap_content"
                android:layout_weight="1"
                android:text="put"/>
        </LinearLayout>

        <androidx.recyclerview.widget.RecyclerView
            android:id="@+id/rv"
            android:layout_width="match_parent"
            android:layout_height="0dp"
            android:layout_weight="1"/>
        <TextView
            android:id="@+id/inputText"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="@{input.num}"
            android:textSize="30dp"
            android:layout_gravity="center"
            android:textColor="@color/black"/>

    </LinearLayout>
</layout>

Test.kt

data class Test (
    val num:String
)

위의 Test 데이터 클래스를 DataBinding 패키지 안에 생성해서 실행을 했더니 자꾸 Test의 위치를 못찾겠다는 오류가 나왔다.
(Check your module classpath for missing or conflicting dependencies
inferred type is com.example.jetpackstudy.DataBinding.Test but DataBinding.Test? was expected
)
구글링을 해보니 'Binding' 이라는 키워드가 들어가는 곳 안에 있으면 생기는 오류라고 했다.
https://stackoverflow.com/questions/53013130/type-mismatch-inferred-type-is-but-was-expected
그래서 패키지 안에서 빼내니 잘 실행됐다.

실행화면




ViewBinding과 DataBinding을 사용하여 recyclerview를 만들어보았다.
역시 난 아직 갈 길이 멀구나를 느꼈다...
아직도 리사이클러뷰가 낯설다니 큰일이네

profile
발전중

0개의 댓글