【问题标题】:how to add and delete <Object> from (and to) LiveData<List<Object>>?如何在 LiveData<List<Object>> 中添加和删除 <Object>?
【发布时间】:2021-01-12 23:48:16
【问题描述】:

我有一个用 LiveData currentList 填充的 recyclerView。 我采用 Single 并在 onSuccess 方法中使用 currentList.setValue(people) 添加人员(请参见下面的代码)。 但是当我打开应用程序时,recyclerView 中只有 1 个对象。 我的任务是: 1)当应用程序打开时,它必须将 4 个人添加到 recyclerView(即 currentList); 2) 在 onSwipe 方法之后,它必须从 RoomDatabase 中删除第一个并添加 1 个新随机数到 currentList 的末尾。

这意味着我需要将对象删除和添加到 LiveData 的方法。 我怎样才能做到这一点? (ViewModel 代码如下)

public class PersonViewModel extends AndroidViewModel {
    private PersonRepository mRepository;
    private CompositeDisposable composite = new CompositeDisposable();
    private Single<List<Person>> mGuyWho;     // это нада??? LOBNYA
    private Single<Person> mGuy;      // PSKOV
    private MutableLiveData<List<Person>> currentList = new MutableLiveData<>();
    public PersonViewModel(@NonNull Application application) {
        super(application);
        mRepository = new PersonRepository(application);

        mGuyWho = mRepository.getGuyWho(); //это нада?? LOBNYA
        mGuy = mRepository.getGuy(); // PSKOV

        mGuyWho.subscribeOn(Schedulers.io())   // LOBNYA nachalo
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(new SingleObserver<List<Person>>() {
                    @Override
                    public void onSubscribe(Disposable d) {
                        Log.d(TAG, "onSubscribe(Disposable d): called");
                        composite.add(d);
                    }

                    @Override
                    public void onSuccess(List<Person> people) {
                        Log.d(TAG, "onSuccess: called");
                        currentList.setValue(people); // here I pass List to LiveData<List>
                    }

                    @Override
                    public void onError(Throwable e) {
                        Log.d(TAG, "onError: called");
                        Toast.makeText(application, "NO DATA", Toast.LENGTH_SHORT).show();
                    }
                });  // LOBNYA konets

        mGuy.subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(new SingleObserver<Person>() {
                    @Override
                    public void onSubscribe(Disposable d) {
                        Log.d(TAG, "onSubscribe(Disposable d): called");
                        composite.add(d);
                    }

                    @Override
                    public void onSuccess(Person person) {
                        Log.d(TAG, "onSuccess: called");
                        currentList.setValue(person); // there is an error, for I cannot bypass <Person> to LiveData<List<>>
                    }

                    @Override
                    public void onError(Throwable e) {
                        Log.d(TAG, "onError: called");
                    }
                })
        }
    LiveData<List<Person>> getCurrentList() {
        return currentList;
    }
};

【问题讨论】:

    标签: java android mvvm rx-java2 android-livedata


    【解决方案1】:

    您的LiveDataList&lt;Person&gt; 对象组成:

    private MutableLiveData<List<Person>> currentList = new MutableLiveData<>();
    

    在您的onSuccess() 方法中,您正试图向它传递一个Person 对象。您应该在其中传递 mutableListOf(Person()) 以使其正常工作。 但是,这仍然不能解决您的问题。

    你需要做的是:

    1. 接收 ViewHolder 的 onSwipe 事件并在您的 viewModel 中调用 remove 方法。
    2. 这个remove 方法应该通过删除元素来修改你的currentList。您可以将id 传递给remove 方法以简化操作。
    3. 因为currentListLiveData 每个observer 都会收到通知。
    4. 那么你需要从Room Database获取随机条目。
    5. 将此随机条目添加到currentList。为此,您可以使用LiveDataTransformations API。
    6. 再一次,因为currentListLiveData,每个Observer 都会收到通知。

    【讨论】:

    • 非常感谢。但是 ViewModel 中的 remove 方法应该是什么样子? (鉴于我必须从 Livedata 中删除)
    • private MutableLiveData&lt;List&lt;Person&gt;&gt; currentList = new MutableLiveData&lt;&gt;(); List本质上不是mutable,即不能添加和删除。为此,最好使用ArrayList。届时,您只需拨打名单上的currentList.remove(element)
    • 我的适配器无法识别滑动删除了哪个项目。当我滑动时,当前的 被更新和删除;但是当我下一次滑动时, 会更新并从 中删除,但不会从 View 中删除;同时从 View 中删除第三个 (因为适配器试图找到 item #1 而不是 #0,而在删除 item #0 后,item #1 已成为 item #0,而 item #2 已分别成为item #1,但是适配器不知道这个,我不明白如何同步这个..)
    • 您不会在adapter 上设置这些操作,因为adapter's 的工作是管理List 本身,而不是elements。在ViewHolder 类中设置这些onClickListeners。您的 ViewHolder 将具有 Person 元素。一个干净的解决方案是创建一个EventListener 接口。将此EventListener 作为argument 传递给adapterEventListener 实例显然是您的 viewModel。同样在RecyclerViewonBindInstance() 方法中,也将EventListener 传递给ViewHolder,因此您的viewModel 实例将包含在ViewHolder 中。
    • 观看this
    猜你喜欢
    • 2019-06-06
    • 2019-04-06
    • 1970-01-01
    • 2017-11-27
    • 2015-05-23
    • 2019-06-20
    • 1970-01-01
    • 1970-01-01
    • 2012-04-16
    相关资源
    最近更新 更多