为了账号安全,请及时绑定邮箱和手机立即绑定

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

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

智慧大石 2022-05-21 19:54:42
我使用LiveData+ Transformations.map():private final LiveData<List<Task>> observableTasks;(...)observableTasks =  Transformations.map(tasksRepository.getTasks(), tasks-> filterTasks(tasks));如何强制LiveData刷新?我需要Transformations.map()准备新的清单。当用户更改过滤选项时,我需要filterTasks(tasks)再次调用并显示新的排序列表。来自存储库 ( tasksRepository.getTasks()) 的数据保持不变。
查看完整描述

3 回答

?
眼眸繁星

TA贡献1873条经验 获得超9个赞

根据您提供的信息,我执行了以下步骤,并且我的 observable 已按预期触发。我认为您在存储库或处理转换的类中做错了什么。由于没有足够的代码检查,我创建了自己的虚拟类:


我创建了虚拟任务 POJO:

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;

    }

}

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

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;

    }

}

创建了一个名为 MyViewModel 的类,它可以处理转换。在转换过程中,我们只需将“TEST”前缀添加到任务 ID。您可以将其与您的代码进行比较,它应该没问题:

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;

    }

}

在单击按钮时添加数据并观察数据变化:

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})));


查看完整回答
反对 回复 2022-05-21
?
一只萌萌小番薯

TA贡献1795条经验 获得超7个赞

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


    observableTasks = Transformations.switchMap(filterChangeEvent, input -> {

        final MediatorLiveData<List<Tasks>> result = new MediatorLiveData<>();

        result.addSource(tasksRepository.getTasks(), tasks -> result.setValue(filterTasks(tasks)));

        return result;

    });


查看完整回答
反对 回复 2022-05-21
?
慕尼黑8549860

TA贡献1818条经验 获得超11个赞

设想:

在存储库包含 User(1, "Jane") 和 User(2, "John") 的场景中,当 userIdLiveData 值设置为“1”时,switchMap 将调用 getUser(1),这将返回一个 LiveData包含值 User(1, "Jane")。所以现在,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 作为源被删除。


查看完整回答
反对 回复 2022-05-21
  • 3 回答
  • 0 关注
  • 117 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信