DBILITY

안드로이드 RecyclerView 기초 사용법 ( viewMoldel 적용 ) 본문

android/kotlin

안드로이드 RecyclerView 기초 사용법 ( viewMoldel 적용 )

DBILITY 2024. 3. 7. 15:26
반응형

https://hyperrookie.tistory.com/730

 

안드로이드 RecyclerView 기초 사용법

https://developer.android.com/develop/ui/views/layout/recyclerview?hl=ko RecyclerView로 동적 목록 만들기 | Views | Android Developers 이 페이지는 Cloud Translation API를 통해 번역되었습니다. 컬렉션을 사용해 정리하기 내

dbility.com

이전 코드에 viewModel을 적용해 보았다.

import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.launch

class TodoViewModel : ViewModel() {
    private val _items = MutableStateFlow<List<Todo>>(emptyList())
    val items: StateFlow<List<Todo>> = _items
    private val dataList = mutableListOf<Todo>()
    init {
       for (idx in 1..100) {
           dataList.add(Todo(idx,"do something $idx", System.currentTimeMillis()))
       }
        viewModelScope.launch {
            _items.value = dataList
        }
    }
}
import android.os.Bundle
import android.util.Log
import android.view.LayoutInflater
import android.view.ViewGroup
import androidx.activity.enableEdgeToEdge
import androidx.appcompat.app.AppCompatActivity
import androidx.core.view.ViewCompat
import androidx.core.view.WindowInsetsCompat
import androidx.lifecycle.Lifecycle
import androidx.lifecycle.ViewModelProvider
import androidx.lifecycle.lifecycleScope
import androidx.lifecycle.repeatOnLifecycle
import androidx.recyclerview.widget.DiffUtil
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.ListAdapter
import androidx.recyclerview.widget.RecyclerView
import com.example.myrecyclerviewbyviewmodel.databinding.ActivityMainBinding
import com.example.myrecyclerviewbyviewmodel.databinding.ItemViewBinding
import kotlinx.coroutines.launch
import java.text.SimpleDateFormat

class MainActivity : AppCompatActivity() {

    companion object {
        private const val TAG = "LOG"
    }

    private val binding by lazy {
        ActivityMainBinding.inflate(layoutInflater)
    }

    //private val viewModel:TodoViewModel by viewModels()
    private lateinit var viewModel: TodoViewModel
    private val dateFormatter = SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS")
    private val todoListAdapter = TodoListAdapter { data->
        Log.d(TAG, data.todo)
    }

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        enableEdgeToEdge()
        setContentView(binding.root)
        ViewCompat.setOnApplyWindowInsetsListener(binding.main) { v, insets ->
            val systemBars = insets.getInsets(WindowInsetsCompat.Type.systemBars())
            v.setPadding(systemBars.left, systemBars.top, systemBars.right, systemBars.bottom)
            insets
        }

        viewModel = ViewModelProvider(this)[TodoViewModel::class.java]

        lifecycleScope.launch {
            repeatOnLifecycle(Lifecycle.State.STARTED) {
                viewModel.items.collect {
                    Log.d(TAG, it.toString())
                    todoListAdapter.submitList(it)
                }
            }
        }
        with(binding) {
            androidMainRecyclerView.apply {
                layoutManager = LinearLayoutManager(root.context)
                itemAnimator = null
                adapter = todoListAdapter
            }
        }

    }

    inner class TodoListAdapter(private val onClickListener: (Todo) -> Unit) :
        ListAdapter<Todo, TodoViewHolder>(TodoDiffItemCallback()) {
        private lateinit var itemViewBinding: ItemViewBinding
        override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): TodoViewHolder {
            itemViewBinding =
                ItemViewBinding.inflate(LayoutInflater.from(parent.context), parent, false)
            return TodoViewHolder(itemViewBinding, onClickListener)
        }

        override fun onBindViewHolder(holder: TodoViewHolder, position: Int) {
            holder.bind(getItem(position))
        }
    }

    inner class TodoViewHolder(
        private val itemViewBinding: ItemViewBinding,
        private val onClickListener: (Todo) -> Unit
    ) :
        RecyclerView.ViewHolder(itemViewBinding.root) {
        fun bind(todo: Todo) {
            with(itemViewBinding) {
                itemViewId.text = todo.id.toString()
                itemViewTodo.text = todo.todo
                itemViewDatetime.text = dateFormatter.format(todo.datetime)
                root.setOnClickListener {
                    onClickListener(todo)
                }
            }
        }
    }

    inner class TodoDiffItemCallback : DiffUtil.ItemCallback<Todo>() {
        override fun areItemsTheSame(oldItem: Todo, newItem: Todo): Boolean {
            return oldItem.id == newItem.id
        }

        override fun areContentsTheSame(oldItem: Todo, newItem: Todo): Boolean {
            return oldItem == newItem
        }
    }
}

ViewModelProvider를 사용하지 않고, private val viewModel:TodoViewModel by viewModels()처럼 사용하려면

fragment-ktx를 dependancy에 추가해야 한다.

반응형
Comments