Как написать класс адаптера для следующего представления переработчика? - PullRequest
0 голосов
/ 10 апреля 2020

Я пытаюсь создать приложение Todo, и я выполнил часть Room и теперь могу хранить данные. Я хочу отобразить данные в форме Recycler View, но я не понимаю, как написать соответствующий класс адаптера. , Я искал его на разных сайтах, так и не получил удовлетворительного ответа.

** TodoFragViewModel.kt ""

class TodofragViewModel(
    val database: TodoDao, applicaltion: Application
): AndroidViewModel(applicaltion) {
    // TODO: Implement the ViewModel
    /**
     * viewModelJob allows us to cancel all coroutines started by this ViewModel.
     */
    private var viewModelJob = Job()

    /**All coroutines can be cancelled by viewmodelJob.cancel() and Dispatcher.main is byDefault choice
     */
    private val uiScope = CoroutineScope(Dispatchers.Main + viewModelJob)

    private val currenctTodo = MutableLiveData<Todo?>()

    private val allTodo = database.getAllTodo()


    init{
        intializeThisTodo()
    }

    private fun intializeThisTodo(){
        uiScope.launch {
            currenctTodo.value=getFromDatabase()
        }
    }

    private suspend fun getFromDatabase(): Todo? {
        return  withContext(Dispatchers.IO){
            val info =database.getCurrentTodo()
            info

        }
    }



    private suspend fun insert(thisTodo: Todo) {

        withContext(Dispatchers.IO) {

            database.insert(thisTodo)
            Log.i("Database","${database.getCurrentTodo()?.description} and ${database.getCurrentTodo()?.time}")
        }


    }


    fun onAdded(time:String,description:String) {

        uiScope.launch {

            val thisTodo = Todo(time,description)

            insert(thisTodo)

            currenctTodo.value=getFromDatabase()


        }

    }


    /**
     * Called when the ViewModel is dismantled.
     * At this point, we want to cancel all coroutines;
     * otherwise we end up with processes that have nowhere to return to
     * using memory and resources.
     */
    override fun onCleared() {
        super.onCleared()
        viewModelJob.cancel()
    }

}

todo_recycler_view


<androidx.cardview.widget.CardView 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:layout_width="match_parent" android:layout_height="wrap_content">
<androidx.constraintlayout.widget.ConstraintLayout
    android:layout_width="match_parent"
    android:layout_height="wrap_content">

    <TextView
        android:id="@+id/date_text"
        android:layout_width="0dp"
        android:layout_height="match_parent"
        android:layout_marginStart="16dp"
        android:layout_marginTop="16dp"
        android:layout_marginEnd="16dp"
        android:text="TextView"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintHorizontal_bias="0.0"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <TextView
        android:id="@+id/todo_description"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginStart="16dp"
        android:layout_marginTop="16dp"
        android:layout_marginEnd="16dp"
        android:text="TextView"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/date_text" />


</androidx.constraintlayout.widget.ConstraintLayout>

TodoFrag.kt


class todofrag : Fragment() {

    companion object {
        fun newInstance() = todofrag()
    }

    private lateinit var viewModel: TodofragViewModel

    override fun onCreateView(
        inflater: LayoutInflater, container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {
        return inflater.inflate(R.layout.todofrag_fragment, container, false)
    }

    override fun onActivityCreated(savedInstanceState: Bundle?) {
        super.onActivityCreated(savedInstanceState)
        val application = requireNotNull(this.activity).application
        val dataSource= TodoDatabase.getInstance(application)?.InformationDatabaseDao

        val viewModelFactory = dataSource?.let { TodoViewModelFactory(it, application) }
        val viewModel=ViewModelProviders.of(this,viewModelFactory).get(TodofragViewModel::class.java)


        add_button.setOnClickListener{
            val currentDate: String = SimpleDateFormat("dd/MM/yyyy", Locale.getDefault()).format(Date())
            val currentTime: String = SimpleDateFormat("HH:mm:ss", Locale.getDefault()).format(Date())

            val time:String="${currentDate} \n ${currentTime}"

            viewModel.onAdded(time,todo_text.text.toString())

        }

    }

}

Пожалуйста, дайте мне знать, если какие-либо другие файлы добавляются. Кстати, я пытался использовать вид карты, чтобы она выглядела хорошо.

1 Ответ

0 голосов
/ 11 апреля 2020

Документация для разработчиков объясняет это довольно хорошо.

Это может не совсем подходить для того, что вам нужно, но это должно быть хорошим началом. В частности, я не знаю всех полей для вашего класса Todo, поэтому убедитесь, что вы учитываете эти поля в этом коде.

В принципе, вы захотите иметь ViewHolder, который представляет ваш CardView

class TodoViewHolder(convertView: View) : RecyclerView.ViewHolder(convertView) {
  val dateText = convertView.findViewById(R.id.date_text)
  val description = convertView.findViewById(R.id.todo_description)
  // whatever else you need access to
}

И вы захотите использовать DiffUtil для лучшего взаимодействия с пользователем. Это позволяет использовать некоторые анимации при изменении элементов в списке, такие как удаление элемента, редактирование элемента или добавление элемента.

private class TodoDiffCallback : DiffUtil.ItemCallback<Todo>() {
  override fun areItemsTheSame(oldItem: Todo, newItem: Todo) =
    oldItem.id == newItem.id

  override fun areContentsTheSame(oldItem: Todo, newItem: Todo) =
    oldItem.dateText == newItem.dateText && oldItem.description == newItem.description

}

Вы захотите расширить ListAdapter и переопределить его методы. onCreateViewHolder создает экземпляр вашего TodoViewHolder для каждого видимого представления, а onBindViewHolder позволяет вам добавить поведение к каждому элементу в списке. Стоит отметить, что вы можете передать параметр в адаптер в случае необходимости.

class MyListAdapter : ListAdapter<Todo, TodoViewHolder>(TodoDiffCallback()) {
  override fun onCreateViewHolder(parent: ViewGroup, viewType: Int) = TodoViewHolder(LayoutInflater.from(parent.context).inflate(R.layout.todo_recycler_view, parent, false))

  override fun onBindViewHolder(holder: TodoViewHolder, position: Int) {
    val todo = getItem(position)
    holder.dateText = todo.dateText
    holder.description = todo.description
    // add whatever click listener and other stuff you need
  }
}

В вашем фрагменте, когда вы получаете доступ к RecyclerView, просто добавьте экземпляр адаптера, если он нулевой.

if (recyclerView.adapter == null) {
  recyclerView.adapter = TotoListAdapter()
}

А когда вы хотите добавить данные (которые вы получили из Room или вашего API) в адаптер (во фрагменте / задании), просто сделайте следующее:

(recyclerView.adapter as? TodoListAdapter)?.submitList(data)

Обратите внимание, чтобы очистить свой стиль (вы можете использовать команду Reformat Code в меню Code), и вы захотите переименовать todo_recycler_view во что-то вроде todo_view. Вам понадобится макет RecyclerView в макете фрагмента.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...