How to bind a view model variable with custom class type

前端 未结 2 1196
栀梦
栀梦 2021-01-29 06:06

What works?

XML:

            name=\"viewModel\"
            type=\"com. . . . .MyViewModel\" />
...
...
...


        
相关标签:
2条回答
  • 2021-01-29 06:42

    IF you wish bind List to RecyclerView.

    Steps to follow.

    1- Create a RecyclerView inside xml files with app:items tag to set items to bind to

     <androidx.recyclerview.widget.RecyclerView
            android:layout_width="match_parent"
            android:id="@+id/recycler_view"
            android:layout_height="match_parent"
            android:scrollbars="vertical"
            app:items="@{viewmodel.items}"
            app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager" />
    

    2- Create layout for rows of RecyclerView lists. Items should have SomeObject as variable.

    <?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">
    
        <data>
    
            <import type="android.widget.CompoundButton" />
    
            <variable
                name="task"
                type="com...data.model.Task" />
    
            <variable
                name="viewmodel"
                type="com...TaskListViewModel" />
        </data>
    
        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="?android:attr/listPreferredItemHeight"
            android:orientation="horizontal"
            android:onClick="@{() -> viewmodel.openTask(task.id)}">
    
            <CheckBox
                android:id="@+id/complete"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_gravity="center_vertical"
                android:onClick="@{(view) -> viewmodel.completeTask(task, ((CompoundButton)view).isChecked())}"
                android:checked="@{task.completed}" />
    
            <TextView
                android:id="@+id/title"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_gravity="center_vertical"
                android:layout_marginLeft="@dimen/activity_horizontal_margin"
                android:layout_marginStart="@dimen/activity_horizontal_margin"
                android:textAppearance="@style/TextAppearance.AppCompat.Title"
                android:text="@{task.titleForList}"
                app:completedTask="@{task.completed}" />
        </LinearLayout>
    </layout>
    

    3- Use ListAdapter, this is new and calculates line differences by itself and on a worker thread, instead of RecyclerView.Adapter and bind SomeObject and ViewModel to this adapter.

    /** * Adapter for the task list. Has a reference to the [TaskListViewModel] to send actions back to it. */

    class TasksAdapter(private val viewModel: TaskListViewModel) :
            ListAdapter<Task, CustomViewHolder>(TaskDiffCallback()) {
    
        override fun onBindViewHolder(holder: CustomViewHolder, position: Int) {
            val item = getItem(position)
    
            holder.bind(viewModel, item)
        }
    
        override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): CustomViewHolder {
            return CustomViewHolder.from(parent)
        }
    
        class CustomViewHolder private constructor(val binding: TaskItemBinding) :
                RecyclerView.ViewHolder(binding.root) {
    
            fun bind(viewModel: TaskListViewModel, item: Task) {
    
                binding.viewmodel = viewModel
                binding.task = item
                binding.executePendingBindings()
            }
    
            companion object {
                fun from(parent: ViewGroup): CustomViewHolder {
                    val layoutInflater = LayoutInflater.from(parent.context)
                    val binding = TaskItemBinding.inflate(layoutInflater, parent, false)
    
                    return CustomViewHolder(binding)
                }
            }
        }
    }
    
    /**
     * Callback for calculating the diff between two non-null items in a list.
     *
     * Used by ListAdapter to calculate the minimum number of changes between and old list and a new
     * list that's been passed to `submitList`.
     */
    class TaskDiffCallback : DiffUtil.ItemCallback<Task>() {
        override fun areItemsTheSame(oldItem: Task, newItem: Task): Boolean {
            return oldItem.id == newItem.id
        }
    
        override fun areContentsTheSame(oldItem: Task, newItem: Task): Boolean {
            return oldItem == newItem
        }
    }
    
    0 讨论(0)
  • 2021-01-29 06:47

    Change this like below in viewmodel

       private MutableLiveData<List<Feed>> feedListLivedata =  new MutableLiveData<>();;
    
    
    
     public MyViewModel() {
        //create a list of feed here
        setFeeds(feeds);
    }
    
    
    
    public void setFeeds( List<Feed>  feeds) {
            feedListLivedata .postValue(feeds);
        }
    

    //create getter and setter for feed list live data.

    And now in xml

     app:items="@{viewModel.feedListLivedata }"
    
    0 讨论(0)
提交回复
热议问题