【问题标题】:How to make changes in MutableLivedata<List<Obj>> (removing item + addin a new item) from UI?如何从 UI 中更改 MutableLivedata<List<Obj>>(删除项目 + 添加新项目)?
【发布时间】:2021-01-14 02:55:31
【问题描述】:

所以,我需要在滑动项目后,从当前 mlist 中删除该项目,并从数据库中获取一个新项目并 添加到列表末尾。

  1. 删除项目我需要在哪里和写什么;
  2. 通过从 RoomDB 添加新项目来更改当前的 mList,我需要在哪里写什么? (getPerson() 方法在 ViewModel 中)

在道:

@Query("SELECT * FROM person_table WHERE status = :statusname ORDER BY RANDOM() LIMIT 3")
Single<List<Person>> getThreePersons(String statusname);

@Query("SELECT * FROM person_table WHERE status = :statusname ORDER BY RANDOM() LIMIT 1")
Single<List<Person>> getPerson(String statusname);

在回购中:

PersonRepository(Application application) {
    PersonRoomDatabase db = PersonRoomDatabase.getDatabase(application);
    mPersonDao = db.PersonDao();
    mThreePersons = mPersonDao.getThreePersons(MUDAK);
    mPerson = mPersonDao.getPerson(MUDAK);
}
Single<List<Person>> getThreePersons() {return mThreePersons;} // to get 3 persons to initially fulfill the working List<>
Single<List<Person>> getPerson() {return mPerson;}   // to get 1 person from Romm DB

在 ViewModel 中:

public class PersonViewModel extends AndroidViewModel {
    private PersonRepository mRepository;
    private CompositeDisposable composite = new CompositeDisposable();
    private Single<List<Person>> mThreePersons;     
    private Single<List<Person>> mPerson;      
    private ArrayList<Person> mList = new ArrayList<>();
    private MutableLiveData<List<Person>> mListLivedata = new MutableLiveData<>();
    public PersonViewModel(@NonNull Application application) {
        super(application);
        mRepository = new PersonRepository(application);
        mThreePersons = mRepository.getThreePersons();
        mPerson = mRepository.getPerson(); 

        mThreePersons.subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(new SingleObserver<List<Person>>() {
                    @Override
                    public void onSubscribe(Disposable d) {
                        composite.add(d);
                    }

                    @Override
                    public void onSuccess(List<Person> people) {
                        mList.addAll(people);
                        mListLivedata.setValue(mList); // here I get 3 Persons from RoomDB to fill the list, evrthing works OK
                    }

                    @Override
                    public void onError(Throwable e) {
                        Toast.makeText(application, "OnError called", Toast.LENGTH_SHORT).show();
                    }
                });
    }
    LiveData<List<Person>> getListLivedata() {
        return mListLivedata;
    }
}           

活动中:

public class MainActivity extends AppCompatActivity implements CardStackListener {
    private CardStackView personCardStackView;
    private PersonAdapter personAdapter;
    private CardStackLayoutManager personCardStackLayoutManager;
    private PersonViewModel personViewModel;
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        mudakViewModel = new ViewModelProvider(this,
            ViewModelProvider.AndroidViewModelFactory.getInstance(this.getApplication()))
            .get(PersonViewModel.class);
        mudakViewModel.getListLivedata().observe(this, personList -> {
        mudakAdapter.submitList(personList);
    });
    personCardStackView = findViewById(R.id.card_stack_view);
    personCardStackLayoutManager = new CardStackLayoutManager(this, this);
    personAdapter = new PersonAdapter(new PersonAdapter.PersonDiff()); 
    personCardStackView.setLayoutManager(personCardStackLayoutManager);
    personCardStackView.setAdapter(personAdapter);
    // other methods
}
public void onCardSwiped(Direction direction) {
    //some methods updating current item. After onSwiped, when item has gone beyond the screen onCardDisappeared is called, see below
}
public void onCardDisappeared(View view, int position) {
    mudakCurrentPerson = mudakAdapter.getPersonAt(position);
    // here I need to call method for 1)removing swiped <Item> from LiveData<List<...>> and 2)adding a new random <Item> from-
    // from RoomDB, using getPerson() method which is initialized in ViewModel already
}

来自适配器的东西(如果需要):

public class MudakAdapter extends ListAdapter<Person, MudakAdapter.MudakViewHolder> {
    protected MudakAdapter(@NonNull DiffUtil.ItemCallback<Person> diffCallback) {
        super(diffCallback);
    }
    // methods, holder etc ......
    @Override
        public void onBindViewHolder(@NonNull MudakViewHolder holder, int position) {
            Person currentPerson = getItem(position);
            holder.mName.setText(currentPerson.getName());
            holder.mStatus.setText(currentPerson.getStatus());
        }


        public Person getPersonAt(int position) {
            return getItem(position);
        }
}

【问题讨论】:

    标签: java android mvvm android-room android-livedata


    【解决方案1】:

    您可以使用 LiveDataReactiveStreams。它允许您一起使用 RxJava 和 LiveData。从您的房间数据库返回 Flowable 而不是单个。例如:

    @Query("SELECT * FROM person_table WHERE status = :statusname ORDER BY RANDOM() LIMIT 1")
    Flowable<List<Person>> getPerson(String statusname);
    

    然后在您的 ViewModel 中,您可以使用 LiveDataReactiveStreams 将此 flowable 转换为 LiveData。看下面的例子:

    LiveData<List<Person>> = LiveDataReactiveStreams.fromPublisher(respository.getPerson());
     
    

    现在,无论何时添加新项目或删除现有项目,列表都会由 flowable 自动发送到您可以在 UI 中观察到的 LiveData。

    将此添加到您的 Gradle 中。将 替换为最新版本。

    implementation "androidx.lifecycle:lifecycle-reactivestreams:<specific_version>"
    

    您可以阅读有关 LiveDataReactiveStreams 的更多信息here

    【讨论】:

    • 非常感谢,但我仍然不明白如何将项目删除/添加到 UI 正在观察的列表中..
    • 我的适配器不理解滑动删除了哪个项目。当我滑动时,当前的 被更新和删除;但是当我下一次滑动时, 会更新并从 中删除,但不会从 View 中删除;同时从 View 中删除第三个 (因为适配器试图找到 item #1 而不是 #0,而在删除 item #0 后,item #1 已成为 item #0,而 item #2 已分别成为item #1,但是适配器不知道这个,我不明白如何同步这个..)
    猜你喜欢
    • 1970-01-01
    • 2019-01-26
    • 2014-07-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-04-27
    • 1970-01-01
    相关资源
    最近更新 更多