LiveData, Transformations.map () - как заставить обновляться, когда пользователь меняет порядок фильтрации? - PullRequest
0 голосов
/ 25 января 2019

Я использую 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 ]

0 голосов
/ 25 января 2019

На основании предоставленной вами информации я сделал следующие шаги, и моя наблюдаемая была запущена, как и ожидалось. Я думаю, что вы делаете что-то не так в хранилище или в классе, где вы обрабатываете преобразование. Поскольку кода для проверки недостаточно, я создал собственные фиктивные классы:

  1. Я создал фиктивную задачу. 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;
    }
}
  1. Я создал фиктивное хранилище с 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;
    }
}
  1. Создан класс MyViewModel, который может обрабатывать преобразования. Во время преобразования мы просто добавляем префикс «TEST» к идентификатору задачи. Вы можете сравнить его с вашим кодом, и все должно быть в порядке:
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. Добавить данные о нажатии кнопки и наблюдать за изменениями данных:
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})));
0 голосов
/ 07 февраля 2019

Оформить заказ Transformation.switchMap. Это объясняет следующий случай, когда его использовать.)

Сценарий:

В сценарии, где хранилище содержит 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»).

Когда метод setUserId вызывается с userId = "2", значение userIdLiveData изменяется и автоматически запускает запрос на получение пользователя с идентификатором "2" из хранилища. Итак, userLiveData испускает User (2, «Джон»). LiveData, возвращаемый repository.getUserById (1), удаляется как источник.

0 голосов
/ 25 января 2019

Я думаю, что нашел решение. Я создал дополнительное LiveData поле filterChangeEvent. Каждый раз, когда пользователь меняет порядок фильтрации, новое значение устанавливается на filterChangeEvent. Затем я использую switchMap с filterChangeEvent в качестве триггера:

    observableTasks = Transformations.switchMap(filterChangeEvent, input -> {
        final MediatorLiveData<List<Tasks>> result = new MediatorLiveData<>();
        result.addSource(tasksRepository.getTasks(), tasks -> result.setValue(filterTasks(tasks)));
        return result;
    });
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...