首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >LiveData,Transformations.map() -当用户改变过滤顺序时如何强制刷新?

LiveData,Transformations.map() -当用户改变过滤顺序时如何强制刷新?
EN

Stack Overflow用户
提问于 2019-01-25 17:11:56
回答 3查看 4.1K关注 0票数 4

我使用LiveData + Transformations.map()

代码语言:javascript
复制
private final LiveData<List<Task>> observableTasks;
(...)
observableTasks =  Transformations.map(tasksRepository.getTasks(), tasks-> filterTasks(tasks));

如何强制LiveData刷新?我需要Transformations.map()准备新的名单。当用户更改过滤选项时,我需要再次调用filterTasks(tasks)并显示新的排序列表。来自存储库(tasksRepository.getTasks())的数据保持不变。

EN

回答 3

Stack Overflow用户

发布于 2019-01-25 20:57:47

我想我找到解决方案了。我创建了额外的LiveData字段filterChangeEvent。用户每次更改过滤顺序时,都会将新值设置为filterChangeEvent。然后我使用带有filterChangeEventswitchMap作为触发器:

代码语言:javascript
复制
    observableTasks = Transformations.switchMap(filterChangeEvent, input -> {
        final MediatorLiveData<List<Tasks>> result = new MediatorLiveData<>();
        result.addSource(tasksRepository.getTasks(), tasks -> result.setValue(filterTasks(tasks)));
        return result;
    });
票数 1
EN

Stack Overflow用户

发布于 2019-01-25 21:08:55

根据您提供的信息,我执行了以下步骤,我的观察值如预期的那样被触发。我认为,无论是在存储库中还是在处理转换的类中,您都做错了什么。由于没有足够的代码进行检查,我创建了自己的虚拟类:

  1. 我创建了虚拟任务POJO:

代码语言:javascript
复制
public class Task {
    private String id;

    public Task(String id) {
        this.id = id;
    }

    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

    @NonNull
    @Override
    public String toString() {
        return "Task id is " +id;
    }
}

  1. 我创建了具有LiveData的虚拟存储库:

代码语言:javascript
复制
public class TasksRepository {
    private List<Task> taskList = new ArrayList<>();
    private MutableLiveData<List<Task>> _tasks = new MutableLiveData<>();
    private LiveData<List<Task>> tasks = _tasks;

    public TasksRepository() {
        for (int i = 0; i < 5; i++) {
            taskList.add(new Task(createTaskId()));
        }
        _tasks.setValue(taskList);
    }

    private String createTaskId() {
        return UUID.randomUUID().toString();
    }

    public void addTask() {
        taskList.add(new Task(createTaskId()));
        _tasks.setValue(taskList);
    }

    public LiveData<List<Task>> getTasks() {
        return tasks;
    }
}

  1. 创建了一个名为MyViewModel的类,它可以处理转换。在转换过程中,我们只需在任务id中添加"TEST“前缀。您可以将它与您的代码进行比较,它应该是好的:

代码语言:javascript
复制
public class MyViewModel {
    private final LiveData<List<Task>> observableTasks;

    public MyViewModel(TasksRepository tasksRepository) {
        this.observableTasks = Transformations.map(tasksRepository.getTasks(), this::changeId);
    }

    private List<Task> changeId(List<Task> tasks) {
        List<Task> resultTaks = new ArrayList<>();
        for (Task task : tasks) {
            String newId = "TASK" + task.getId();
            task.setId(newId);
            resultTaks.add(task);
        }
        return resultTaks;
    }

    public LiveData<List<Task>> getObservableTasks() {
        return observableTasks;
    }
}

  1. 在单击按钮时添加数据并观察数据更改:

代码语言:javascript
复制
TasksRepository tasksRepository = new TasksRepository();
MyViewModel viewModel = new MyViewModel(tasksRepository);

button.setOnClickListener(v -> tasksRepository.addTask());

viewModel.getObservableTasks().observe(this,
        tasks -> Log.d(TAG, Arrays.toString(new List[]{tasks})));
票数 1
EN

Stack Overflow用户

发布于 2019-02-08 02:58:40

Checkout Transformation.switchMap. It explains following case when to use it also.)

场景:

在存储库包含用户(1,"Jane")和用户(2,"John")的场景中,当userIdLiveData值设置为"1“时,switchMap将调用getUser(1),这将返回值为User(1,"Jane")的LiveData。现在,userLiveData将发出User(1,"Jane")。当存储库中的用户更新为User(1,"Sarah")时,userLiveData会自动收到通知,并发出User(1,"Sarah")。

当使用userId = "2“调用setUserId方法时,userIdLiveData的值会发生变化,并自动触发从存储库获取id为"2”的用户的请求。因此,userLiveData发出User(2,"John")。repository.getUserById(1)返回的LiveData已作为源删除。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/54362069

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档