Android 获取数据绑定以观察回收器视图的实时数据更改

Android 获取数据绑定以观察回收器视图的实时数据更改,android,data-binding,android-recyclerview,android-livedata,android-jetpack,Android,Data Binding,Android Recyclerview,Android Livedata,Android Jetpack,我已经被困在这个问题上好几个小时了。非常尊敬能帮我解决这个问题的人 每当我更改MutableLiveData时,我的视图都不会更新 在我的训练应用程序中,我有一个使用回收器视图显示的练习列表:MutableLiveData>。recycler视图持有者正在使用数据绑定来显示此ArrayList中的各个练习。每当我更新整个列表(使用setValue)时,我都希望视图更新 但是,由于我的数据绑定xml实际上没有引用MutableLiveData>(),只引用列表中的ExerciseEntity元素,

我已经被困在这个问题上好几个小时了。非常尊敬能帮我解决这个问题的人

每当我更改MutableLiveData时,我的视图都不会更新

在我的训练应用程序中,我有一个使用回收器视图显示的练习列表:MutableLiveData>。recycler视图持有者正在使用数据绑定来显示此ArrayList中的各个练习。每当我更新整个列表(使用setValue)时,我都希望视图更新

但是,由于我的数据绑定xml实际上没有引用MutableLiveData>(),只引用列表中的ExerciseEntity元素,因此我认为它没有观察到任何更改。因此它没有更新。我不知道如何使它正确更新

选择活动:

class SelectorActivity : AppCompatActivity() {
private lateinit var mExerciseSelectAdapter: ExerciseSelectAdapter
private lateinit var mViewModel: SelectorViewModel

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

    mViewModel = ViewModelProviders.of(this).get(SelectorViewModel::class.java)
    mExerciseSelectAdapter = ExerciseSelectAdapter(this, mViewModel)

    setupRecyclerView()
    loadExerciseList(intent.hasExtra("LOAD_FROM_DB"), resources)
}

private fun setupRecyclerView(){
    rv_select_exers.layoutManager = LinearLayoutManager(this)
    rv_select_exers.setHasFixedSize(true)
    rv_select_exers.adapter = mExerciseSelectAdapter
}

private fun loadExerciseList(loadFromDB: Boolean, resources: Resources) {
    doAsync {
           val myDBExercises = loadExersFromDB()
           mViewModel.populateExerciseListFromDB(myDBExercises)
           mExerciseSelectAdapter.notifyDataSetChanged()
        }
    }
}
class SelectorViewModel : ViewModel() {
    private val mExerciseList = MutableLiveData<ArrayList<ExerciseEntity>>()
    val exerciseList : LiveData<ArrayList<ExerciseEntity>>
        get() = mExerciseList

    init {
        mExerciseList.value = ArrayList()
    }

    fun populateExerciseListFromDB(myDBExercises: List<ExerciseEntity>) {
        // .... Load our exer list from DB ... //


        mExerciseList.value?.addAll(myDBExercises)
        // Use the "setValue" method to notify observers of change
        mExerciseList.value = mExerciseList.value
    }

    private fun updateRepsInExercise(exercise: ExerciseEntity, reps1: Int, reps2: Int, reps3: Int) {
        exercise.set1Reps = reps1
        exercise.set2Reps = reps2
        exercise.set3Reps = reps3

        // Force our livedata to detect a change
        // TODO: not doing anything after increment set, our view is not updating
        mExerciseList.value = mExerciseList.value
    }

    fun incrementSet(exercise: ExerciseEntity, smallIncrement: Boolean) {
            // ... Compute the new reps ... //
            updateRepsInExercise(exercise, numReps1, numReps2, numReps3)
    }
}
class ExerciseSelectViewHolder(private val mDataBinding: ExerciseSelectBinding,
                               private val mLifecycleOwner: LifecycleOwner,
                               private val mViewModel: SelectorViewModel):
        RecyclerView.ViewHolder(mDataBinding.root){

    init {
        // Used to enable proper observation of LiveData
        mDataBinding.setLifecycleOwner(mLifecycleOwner)
    }

    fun bindExerciseSelectView(exerciseEntity: ExerciseEntity) {
        mDataBinding.exerciseEntity = exerciseEntity
        mDataBinding.viewModel = mViewModel
        mDataBinding.spinnerAdapter = ArrayAdapter(mLifecycleOwner as Context,
                R.layout.simple_spinner_dropdown_item,
                exerciseEntity.allProgressions)
        // Forces the bindings to run immediately
        mDataBinding.executePendingBindings()
    }
}
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout 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="match_parent"
        tools:context="com.epsilon.startbodyweight.selectorActivity.SelectorActivity">

        <android.support.v7.widget.RecyclerView
            android:id="@+id/rv_select_exers"
            android:layout_width="match_parent"
            android:layout_height="0dp"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="parent" />
    </android.support.constraint.ConstraintLayout>
 <?xml version="1.0" encoding="utf-8"?>
    <layout>
        <data>
            <import type="android.view.View"/>
            <variable
                name="exerciseEntity"
                type="com.epsilon.startbodyweight.data.ExerciseEntity"/>
            <variable
                name="viewModel"
                type="com.epsilon.startbodyweight.selectorActivity.SelectorViewModel"/>
            <variable
                name="spinnerAdapter"
                type="android.widget.ArrayAdapter" />
        </data>
        <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
            <Spinner
                android:id="@+id/sp_sel_exer"
                //... Styling stuff
                android:spinnerMode="dropdown"
                android:adapter="@{spinnerAdapter}"
                android:selection="@{exerciseEntity.progressionNumber}"
                android:onItemSelected="@{(parent,view,position,id) -> viewModel.onItemSelectedSpinner(parent,position,exerciseEntity)}"/>
            <Button
                android:id="@+id/b_sel_increase_reps_small"
                android:layout_width="wrap_content"
                //... Styling stuff
                android:onClick="@{() -> viewModel.incrementSet(exerciseEntity, true)}"
                android:text="↑" />
            <TextView
                android:id="@+id/tv_sel_rep_1"
                // ... Styling stuff
                android:text="@{String.valueOf(exerciseEntity.set1Reps)}"
                android:visibility="@{!exerciseEntity.isTimedExercise ? View.VISIBLE : View.GONE}"/>
            <TextView
                android:id="@+id/tv_sel_rep_2"
                //... Styling stuff
                android:text="@{String.valueOf(viewModel.exerciseList)}"
                android:visibility="@{!exerciseEntity.isTimedExercise ? View.VISIBLE : View.GONE}"/>
            <TextView
                android:id="@+id/tv_sel_rep_3"
                //... Styling stuff
                android:text="@{String.valueOf(exerciseEntity.set3Reps)}"
                android:visibility="@{!exerciseEntity.isTimedExercise ? View.VISIBLE : View.GONE}"/>
        </LinearLayout>
    </layout>
}

选择或查看模型:

class SelectorActivity : AppCompatActivity() {
private lateinit var mExerciseSelectAdapter: ExerciseSelectAdapter
private lateinit var mViewModel: SelectorViewModel

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

    mViewModel = ViewModelProviders.of(this).get(SelectorViewModel::class.java)
    mExerciseSelectAdapter = ExerciseSelectAdapter(this, mViewModel)

    setupRecyclerView()
    loadExerciseList(intent.hasExtra("LOAD_FROM_DB"), resources)
}

private fun setupRecyclerView(){
    rv_select_exers.layoutManager = LinearLayoutManager(this)
    rv_select_exers.setHasFixedSize(true)
    rv_select_exers.adapter = mExerciseSelectAdapter
}

private fun loadExerciseList(loadFromDB: Boolean, resources: Resources) {
    doAsync {
           val myDBExercises = loadExersFromDB()
           mViewModel.populateExerciseListFromDB(myDBExercises)
           mExerciseSelectAdapter.notifyDataSetChanged()
        }
    }
}
class SelectorViewModel : ViewModel() {
    private val mExerciseList = MutableLiveData<ArrayList<ExerciseEntity>>()
    val exerciseList : LiveData<ArrayList<ExerciseEntity>>
        get() = mExerciseList

    init {
        mExerciseList.value = ArrayList()
    }

    fun populateExerciseListFromDB(myDBExercises: List<ExerciseEntity>) {
        // .... Load our exer list from DB ... //


        mExerciseList.value?.addAll(myDBExercises)
        // Use the "setValue" method to notify observers of change
        mExerciseList.value = mExerciseList.value
    }

    private fun updateRepsInExercise(exercise: ExerciseEntity, reps1: Int, reps2: Int, reps3: Int) {
        exercise.set1Reps = reps1
        exercise.set2Reps = reps2
        exercise.set3Reps = reps3

        // Force our livedata to detect a change
        // TODO: not doing anything after increment set, our view is not updating
        mExerciseList.value = mExerciseList.value
    }

    fun incrementSet(exercise: ExerciseEntity, smallIncrement: Boolean) {
            // ... Compute the new reps ... //
            updateRepsInExercise(exercise, numReps1, numReps2, numReps3)
    }
}
class ExerciseSelectViewHolder(private val mDataBinding: ExerciseSelectBinding,
                               private val mLifecycleOwner: LifecycleOwner,
                               private val mViewModel: SelectorViewModel):
        RecyclerView.ViewHolder(mDataBinding.root){

    init {
        // Used to enable proper observation of LiveData
        mDataBinding.setLifecycleOwner(mLifecycleOwner)
    }

    fun bindExerciseSelectView(exerciseEntity: ExerciseEntity) {
        mDataBinding.exerciseEntity = exerciseEntity
        mDataBinding.viewModel = mViewModel
        mDataBinding.spinnerAdapter = ArrayAdapter(mLifecycleOwner as Context,
                R.layout.simple_spinner_dropdown_item,
                exerciseEntity.allProgressions)
        // Forces the bindings to run immediately
        mDataBinding.executePendingBindings()
    }
}
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout 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="match_parent"
        tools:context="com.epsilon.startbodyweight.selectorActivity.SelectorActivity">

        <android.support.v7.widget.RecyclerView
            android:id="@+id/rv_select_exers"
            android:layout_width="match_parent"
            android:layout_height="0dp"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="parent" />
    </android.support.constraint.ConstraintLayout>
 <?xml version="1.0" encoding="utf-8"?>
    <layout>
        <data>
            <import type="android.view.View"/>
            <variable
                name="exerciseEntity"
                type="com.epsilon.startbodyweight.data.ExerciseEntity"/>
            <variable
                name="viewModel"
                type="com.epsilon.startbodyweight.selectorActivity.SelectorViewModel"/>
            <variable
                name="spinnerAdapter"
                type="android.widget.ArrayAdapter" />
        </data>
        <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
            <Spinner
                android:id="@+id/sp_sel_exer"
                //... Styling stuff
                android:spinnerMode="dropdown"
                android:adapter="@{spinnerAdapter}"
                android:selection="@{exerciseEntity.progressionNumber}"
                android:onItemSelected="@{(parent,view,position,id) -> viewModel.onItemSelectedSpinner(parent,position,exerciseEntity)}"/>
            <Button
                android:id="@+id/b_sel_increase_reps_small"
                android:layout_width="wrap_content"
                //... Styling stuff
                android:onClick="@{() -> viewModel.incrementSet(exerciseEntity, true)}"
                android:text="↑" />
            <TextView
                android:id="@+id/tv_sel_rep_1"
                // ... Styling stuff
                android:text="@{String.valueOf(exerciseEntity.set1Reps)}"
                android:visibility="@{!exerciseEntity.isTimedExercise ? View.VISIBLE : View.GONE}"/>
            <TextView
                android:id="@+id/tv_sel_rep_2"
                //... Styling stuff
                android:text="@{String.valueOf(viewModel.exerciseList)}"
                android:visibility="@{!exerciseEntity.isTimedExercise ? View.VISIBLE : View.GONE}"/>
            <TextView
                android:id="@+id/tv_sel_rep_3"
                //... Styling stuff
                android:text="@{String.valueOf(exerciseEntity.set3Reps)}"
                android:visibility="@{!exerciseEntity.isTimedExercise ? View.VISIBLE : View.GONE}"/>
        </LinearLayout>
    </layout>
}

练习选择视图持有者:

class SelectorActivity : AppCompatActivity() {
private lateinit var mExerciseSelectAdapter: ExerciseSelectAdapter
private lateinit var mViewModel: SelectorViewModel

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

    mViewModel = ViewModelProviders.of(this).get(SelectorViewModel::class.java)
    mExerciseSelectAdapter = ExerciseSelectAdapter(this, mViewModel)

    setupRecyclerView()
    loadExerciseList(intent.hasExtra("LOAD_FROM_DB"), resources)
}

private fun setupRecyclerView(){
    rv_select_exers.layoutManager = LinearLayoutManager(this)
    rv_select_exers.setHasFixedSize(true)
    rv_select_exers.adapter = mExerciseSelectAdapter
}

private fun loadExerciseList(loadFromDB: Boolean, resources: Resources) {
    doAsync {
           val myDBExercises = loadExersFromDB()
           mViewModel.populateExerciseListFromDB(myDBExercises)
           mExerciseSelectAdapter.notifyDataSetChanged()
        }
    }
}
class SelectorViewModel : ViewModel() {
    private val mExerciseList = MutableLiveData<ArrayList<ExerciseEntity>>()
    val exerciseList : LiveData<ArrayList<ExerciseEntity>>
        get() = mExerciseList

    init {
        mExerciseList.value = ArrayList()
    }

    fun populateExerciseListFromDB(myDBExercises: List<ExerciseEntity>) {
        // .... Load our exer list from DB ... //


        mExerciseList.value?.addAll(myDBExercises)
        // Use the "setValue" method to notify observers of change
        mExerciseList.value = mExerciseList.value
    }

    private fun updateRepsInExercise(exercise: ExerciseEntity, reps1: Int, reps2: Int, reps3: Int) {
        exercise.set1Reps = reps1
        exercise.set2Reps = reps2
        exercise.set3Reps = reps3

        // Force our livedata to detect a change
        // TODO: not doing anything after increment set, our view is not updating
        mExerciseList.value = mExerciseList.value
    }

    fun incrementSet(exercise: ExerciseEntity, smallIncrement: Boolean) {
            // ... Compute the new reps ... //
            updateRepsInExercise(exercise, numReps1, numReps2, numReps3)
    }
}
class ExerciseSelectViewHolder(private val mDataBinding: ExerciseSelectBinding,
                               private val mLifecycleOwner: LifecycleOwner,
                               private val mViewModel: SelectorViewModel):
        RecyclerView.ViewHolder(mDataBinding.root){

    init {
        // Used to enable proper observation of LiveData
        mDataBinding.setLifecycleOwner(mLifecycleOwner)
    }

    fun bindExerciseSelectView(exerciseEntity: ExerciseEntity) {
        mDataBinding.exerciseEntity = exerciseEntity
        mDataBinding.viewModel = mViewModel
        mDataBinding.spinnerAdapter = ArrayAdapter(mLifecycleOwner as Context,
                R.layout.simple_spinner_dropdown_item,
                exerciseEntity.allProgressions)
        // Forces the bindings to run immediately
        mDataBinding.executePendingBindings()
    }
}
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout 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="match_parent"
        tools:context="com.epsilon.startbodyweight.selectorActivity.SelectorActivity">

        <android.support.v7.widget.RecyclerView
            android:id="@+id/rv_select_exers"
            android:layout_width="match_parent"
            android:layout_height="0dp"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="parent" />
    </android.support.constraint.ConstraintLayout>
 <?xml version="1.0" encoding="utf-8"?>
    <layout>
        <data>
            <import type="android.view.View"/>
            <variable
                name="exerciseEntity"
                type="com.epsilon.startbodyweight.data.ExerciseEntity"/>
            <variable
                name="viewModel"
                type="com.epsilon.startbodyweight.selectorActivity.SelectorViewModel"/>
            <variable
                name="spinnerAdapter"
                type="android.widget.ArrayAdapter" />
        </data>
        <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
            <Spinner
                android:id="@+id/sp_sel_exer"
                //... Styling stuff
                android:spinnerMode="dropdown"
                android:adapter="@{spinnerAdapter}"
                android:selection="@{exerciseEntity.progressionNumber}"
                android:onItemSelected="@{(parent,view,position,id) -> viewModel.onItemSelectedSpinner(parent,position,exerciseEntity)}"/>
            <Button
                android:id="@+id/b_sel_increase_reps_small"
                android:layout_width="wrap_content"
                //... Styling stuff
                android:onClick="@{() -> viewModel.incrementSet(exerciseEntity, true)}"
                android:text="↑" />
            <TextView
                android:id="@+id/tv_sel_rep_1"
                // ... Styling stuff
                android:text="@{String.valueOf(exerciseEntity.set1Reps)}"
                android:visibility="@{!exerciseEntity.isTimedExercise ? View.VISIBLE : View.GONE}"/>
            <TextView
                android:id="@+id/tv_sel_rep_2"
                //... Styling stuff
                android:text="@{String.valueOf(viewModel.exerciseList)}"
                android:visibility="@{!exerciseEntity.isTimedExercise ? View.VISIBLE : View.GONE}"/>
            <TextView
                android:id="@+id/tv_sel_rep_3"
                //... Styling stuff
                android:text="@{String.valueOf(exerciseEntity.set3Reps)}"
                android:visibility="@{!exerciseEntity.isTimedExercise ? View.VISIBLE : View.GONE}"/>
        </LinearLayout>
    </layout>
activity\u selector.xml:

class SelectorActivity : AppCompatActivity() {
private lateinit var mExerciseSelectAdapter: ExerciseSelectAdapter
private lateinit var mViewModel: SelectorViewModel

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

    mViewModel = ViewModelProviders.of(this).get(SelectorViewModel::class.java)
    mExerciseSelectAdapter = ExerciseSelectAdapter(this, mViewModel)

    setupRecyclerView()
    loadExerciseList(intent.hasExtra("LOAD_FROM_DB"), resources)
}

private fun setupRecyclerView(){
    rv_select_exers.layoutManager = LinearLayoutManager(this)
    rv_select_exers.setHasFixedSize(true)
    rv_select_exers.adapter = mExerciseSelectAdapter
}

private fun loadExerciseList(loadFromDB: Boolean, resources: Resources) {
    doAsync {
           val myDBExercises = loadExersFromDB()
           mViewModel.populateExerciseListFromDB(myDBExercises)
           mExerciseSelectAdapter.notifyDataSetChanged()
        }
    }
}
class SelectorViewModel : ViewModel() {
    private val mExerciseList = MutableLiveData<ArrayList<ExerciseEntity>>()
    val exerciseList : LiveData<ArrayList<ExerciseEntity>>
        get() = mExerciseList

    init {
        mExerciseList.value = ArrayList()
    }

    fun populateExerciseListFromDB(myDBExercises: List<ExerciseEntity>) {
        // .... Load our exer list from DB ... //


        mExerciseList.value?.addAll(myDBExercises)
        // Use the "setValue" method to notify observers of change
        mExerciseList.value = mExerciseList.value
    }

    private fun updateRepsInExercise(exercise: ExerciseEntity, reps1: Int, reps2: Int, reps3: Int) {
        exercise.set1Reps = reps1
        exercise.set2Reps = reps2
        exercise.set3Reps = reps3

        // Force our livedata to detect a change
        // TODO: not doing anything after increment set, our view is not updating
        mExerciseList.value = mExerciseList.value
    }

    fun incrementSet(exercise: ExerciseEntity, smallIncrement: Boolean) {
            // ... Compute the new reps ... //
            updateRepsInExercise(exercise, numReps1, numReps2, numReps3)
    }
}
class ExerciseSelectViewHolder(private val mDataBinding: ExerciseSelectBinding,
                               private val mLifecycleOwner: LifecycleOwner,
                               private val mViewModel: SelectorViewModel):
        RecyclerView.ViewHolder(mDataBinding.root){

    init {
        // Used to enable proper observation of LiveData
        mDataBinding.setLifecycleOwner(mLifecycleOwner)
    }

    fun bindExerciseSelectView(exerciseEntity: ExerciseEntity) {
        mDataBinding.exerciseEntity = exerciseEntity
        mDataBinding.viewModel = mViewModel
        mDataBinding.spinnerAdapter = ArrayAdapter(mLifecycleOwner as Context,
                R.layout.simple_spinner_dropdown_item,
                exerciseEntity.allProgressions)
        // Forces the bindings to run immediately
        mDataBinding.executePendingBindings()
    }
}
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout 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="match_parent"
        tools:context="com.epsilon.startbodyweight.selectorActivity.SelectorActivity">

        <android.support.v7.widget.RecyclerView
            android:id="@+id/rv_select_exers"
            android:layout_width="match_parent"
            android:layout_height="0dp"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="parent" />
    </android.support.constraint.ConstraintLayout>
 <?xml version="1.0" encoding="utf-8"?>
    <layout>
        <data>
            <import type="android.view.View"/>
            <variable
                name="exerciseEntity"
                type="com.epsilon.startbodyweight.data.ExerciseEntity"/>
            <variable
                name="viewModel"
                type="com.epsilon.startbodyweight.selectorActivity.SelectorViewModel"/>
            <variable
                name="spinnerAdapter"
                type="android.widget.ArrayAdapter" />
        </data>
        <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
            <Spinner
                android:id="@+id/sp_sel_exer"
                //... Styling stuff
                android:spinnerMode="dropdown"
                android:adapter="@{spinnerAdapter}"
                android:selection="@{exerciseEntity.progressionNumber}"
                android:onItemSelected="@{(parent,view,position,id) -> viewModel.onItemSelectedSpinner(parent,position,exerciseEntity)}"/>
            <Button
                android:id="@+id/b_sel_increase_reps_small"
                android:layout_width="wrap_content"
                //... Styling stuff
                android:onClick="@{() -> viewModel.incrementSet(exerciseEntity, true)}"
                android:text="↑" />
            <TextView
                android:id="@+id/tv_sel_rep_1"
                // ... Styling stuff
                android:text="@{String.valueOf(exerciseEntity.set1Reps)}"
                android:visibility="@{!exerciseEntity.isTimedExercise ? View.VISIBLE : View.GONE}"/>
            <TextView
                android:id="@+id/tv_sel_rep_2"
                //... Styling stuff
                android:text="@{String.valueOf(viewModel.exerciseList)}"
                android:visibility="@{!exerciseEntity.isTimedExercise ? View.VISIBLE : View.GONE}"/>
            <TextView
                android:id="@+id/tv_sel_rep_3"
                //... Styling stuff
                android:text="@{String.valueOf(exerciseEntity.set3Reps)}"
                android:visibility="@{!exerciseEntity.isTimedExercise ? View.VISIBLE : View.GONE}"/>
        </LinearLayout>
    </layout>

这似乎说服了数据绑定最终观察对ArrayList的修改


我不满意,有没有更“最佳实践”的方法来做到这一点?

你知道
PagedListAdapter
简化了很多
RecyclerView
相关的东西(当你的数据集相对较大时,也会使你的应用程序非常快速)?我更不知道这一点,我仍然在学习这个架构。谢谢你的建议,我去看看。如何解决我的问题?当您有大量数据时,您可以使用android分页库进行数据分页。您可以签出MVVM+分页+2+数据绑定+Kotlin。