J'utilise LiveData
+ Transformations.map ()
:
private final LiveData<List<Task>> observableTasks; (...) observableTasks = Transformations.map(tasksRepository.getTasks(), tasks-> filterTasks(tasks));
Comment forcer LiveData
à rafraîchir? J'ai besoin de Transformations.map ()
pour préparer une nouvelle liste. Lorsque l'utilisateur modifie les options de filtrage, je dois appeler à nouveau filterTasks (tâches)
et afficher une nouvelle liste triée. Les données provenant du référentiel ( tasksRepository.getTasks ()
) restent les mêmes.
3 Réponses :
Je pense avoir trouvé la solution. J'ai créé un champ LiveData
supplémentaire filterChangeEvent
. Chaque fois que l'utilisateur change l'ordre de filtrage, la nouvelle valeur est définie sur filterChangeEvent
. Ensuite, j'utilise switchMap
avec filterChangeEvent
comme déclencheur:
observableTasks = Transformations.switchMap(filterChangeEvent, input -> { final MediatorLiveData<List<Tasks>> result = new MediatorLiveData<>(); result.addSource(tasksRepository.getTasks(), tasks -> result.setValue(filterTasks(tasks))); return result; });
Pouvez-vous expliquer pourquoi la carte et pourquoi changer la carte? Je me sens obligé de le comprendre.
Sur la base des informations que vous avez fournies, j'ai suivi les étapes suivantes et mon observable a été déclenché comme prévu. Je pense que vous faites quelque chose de mal dans le référentiel ou en classe où vous gérez la transformation. Comme il n'y a pas assez de code à vérifier, j'ai créé mes propres classes factices:
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})));
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; } }
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; } }
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; } }
Lorsque l'utilisateur change l'option de filtre, rien ne change dans le référentiel, donc la transformation et filterTasks
ne sont pas appelés. Vérifiez ma réponse.
Vous n'avez pas LiveData qui est mis à jour lorsque l'utilisateur change de «filtre»?
Checkout Transformation.switchMap. Il explique le cas suivant quand l'utiliser également.)
Scénario:
Dans un scénario où le référentiel contient User (1, "Jane") et User (2, "John"), lorsque la valeur userIdLiveData est définie sur "1", switchMap appellera getUser (1), cela renvoie un LiveData contenant la valeur User (1, "Jane"). Alors maintenant, le userLiveData émettra User (1, "Jane"). Lorsque l'utilisateur du référentiel est mis à jour en User (1, "Sarah"), userLiveData est automatiquement notifié et émet User (1, "Sarah").
Lorsque la méthode setUserId est appelée avec userId = "2", la valeur de userIdLiveData change et déclenche automatiquement une demande pour obtenir l'utilisateur avec l'ID "2" du référentiel. Ainsi, le userLiveData émet User (2, "John"). Le LiveData renvoyé par repository.getUserById (1) est supprimé en tant que source.
Qu'entendez-vous par forcer
LiveData
à s'actualiser?En utilisant
Private final LiveData
Je peux obtenir de nouvelles valeurs chaque fois que je change les valeurs.> observableTasks = Transformations.map (dataList, this :: addOne);
J'ai besoin d'appeler à nouveau
filterTasks (tasks)
car l'utilisateur a changé l'ordre de filtrage. Les données provenant du référentiel restent les mêmes.pouvez-vous ajouter du code qui déclenche des changements pour l'ordre de filtrage?
Cela peut être par exemple la fonction
changeFilteringOrderTo (EnumFilterOrder enumFilterOrder)
, puisfilterTasks
utilise le champenumFilterOrder
pour décider quoi faire avec la liste.