Не обновляется ViewModel после запроса на модернизацию CREATE

Я использую клиент Retrofit для выполнения HTTP-запросов в простом проекте Android. Когда я отправляю запрос CREATE, элемент успешно создается в удаленной базе данных SQLite, но ViewModel по-прежнему содержит старый список. Когда я перезапускаю свое приложение и снова получаю все элементы с сервера, этот элемент появляется.

Я слежу за Android - Руководство по архитектуре приложений и использую объекты LiveData как в моем репозитории, так и в ViewModel.

Мой фрагмент добавляет наблюдателя к объекту LiveData в ViewModel:

mViewModel.getAllItems().observe(getActivity(), new Observer<List<Item>>() {
            @Override
            public void onChanged(@Nullable final List<Item> items) {
                // Update the cached copy of the words in the adapter.
                mAdapter.setItems(items);
                mAdapter.notifyDataSetChanged();
            }
        });

Функция onChange () запускается после того, как я отправил запрос CREATE, но список элементов не изменился.

Модернизированная версия:

// Retrofit
implementation('com.squareup.retrofit2:retrofit:2.5.0') {
    exclude module: 'okhttp'
}
implementation 'com.squareup.retrofit2:converter-gson:2.1.0'
implementation 'com.squareup.okhttp3:okhttp:3.6.0'
implementation "com.squareup.okhttp3:logging-interceptor:3.6.0"

ИЗМЕНИТЬ

Соответствующий код:

ItemViewModel.java

public class ItemViewModel extends AndroidViewModel {

    private ItemRepository mItemRepository;
    private LiveData<List<Item>> items;

    public ItemViewModel(Application application) {
        super(application);
        this.mItemRepository = new ItemRepository();
    }

    public LiveData<List<Item>> getAllItems() {
        if (this.items == null) {
            this.items = mItemRepository.getAllItems();
        }
        return this.items;
    }

    public void createItem(Item item) {
        this.mItemRepository.createItem(item);
    }

}

ItemRepository.java

public class ItemRepository {

    private WebService mWebservice;
    private MutableLiveData<List<Item>> mAllItems = new MutableLiveData<>();

    public ItemRepository() {
        this.mWebservice = WebClient.getClient().create(WebService.class);
    }

    public LiveData<List<Item>> getAllItems() {
        final MutableLiveData<List<Item>> data = new MutableLiveData<>();
        this.mWebservice.getAllItems().enqueue(new Callback<GetAllItemsResponse>() {
            @Override
            public void onResponse(Call<GetAllItemsResponse> call, Response<GetAllItemsResponse> response) {
                data.setValue(response.body().items);
            }
            @Override
            public void onFailure(Call<GetAllItemsResponse> call, Throwable t) {
                System.out.println(t);
            }
        });
        return data;
    }

    public void insertItem(Item item) {
        mWebservice.createItem(item);
    }

}

person mjkdr    schedule 12.01.2019    source источник
comment
пожалуйста, покажите код класса ur viewmodel   -  person Kamal Kakkar    schedule 12.01.2019
comment
mAdapter.notifyDataSetChanged (); ты пробовал это?   -  person Ashish    schedule 12.01.2019
comment
@Ashish Я вызываю функцию notifyDataSetChanged () в setItems (), но, поскольку список элементов не изменился, View не изменится ..   -  person mjkdr    schedule 12.01.2019


Ответы (2)


Вам просто нужно получить данные, когда вы на самом деле говорите «вы хотите получить данные». Таким образом, вы можете создать LiveData, в котором вы можете получать новые данные.

public class RefreshLiveData<T> extends MutableLiveData<T> {
    public interface RefreshAction<T> {
        private interface Callback<T> {
             void onDataLoaded(T t);
        }

        void loadData(Callback<T> callback);
    }

    private final RefreshAction<T> refreshAction;
    private final Callback<T> callback = new RefreshAction.Callback<T>() {
          @Override
          public void onDataLoaded(T t) {
               postValue(t);
          }
    };

    public RefreshLiveData(RefreshAction<T> refreshAction) {
        this.refreshAction = refreshAction;
    }

    public final void refresh() {
        refreshAction.loadData(callback);
    }
}

Тогда ты можешь сделать

public class YourViewModel extends ViewModel {
    private RefreshLiveData<List<Item>> items;

    private final ItemRepository itemRepository;

    public YourViewModel(ItemRepository itemRepository) {
         this.itemRepository = itemRepository;
         items = itemRepository.getAllItems();
    }

    public void refreshData() {
        items.refresh();
    }

    public LiveData<List<Item>> getItems() {
        return items;
    }
}

И тогда репозиторий может:

public RefreshLiveData<List<Item>> getAllItems() {
    final RefreshLiveData<List<Item>> liveData = new RefreshLiveData<>((callback) -> {
         mWebservice.getAllItems().enqueue(new Callback<List<Item>>() {
            @Override
            public void onResponse(Call<List<Item>> call, Response<List<Item>> response) {
                callback.onDataLoaded(response.body());
            }

            @Override
            public void onFailure(Call<List<Item>> call, Throwable t) {

            }
         });
    });

    return liveData;
}
person EpicPandaForce    schedule 17.01.2019

public class ItemViewModel extends AndroidViewModel {

    private ItemRepository mItemRepository;
    private LiveData<List<Item>> items;

    public ItemViewModel(Application application) {
        super(application);
        this.mItemRepository = new ItemRepository();
    }

    public LiveData<List<Item>> getAllItems() {
//      if (this.items == null) {
            this.items = mItemRepository.getAllItems();
//      }
        return this.items;
    }

    public void createItem(Item item) {
        this.mItemRepository.createItem(item);
    }

}

Попробуйте удалить это, если условие

person Kamal Kakkar    schedule 12.01.2019
comment
Спасибо. К сожалению, это не решает мою проблему. Я думаю, что, повторно создавая объект LiveData каждый раз, когда вы выбираете элементы, Observer, который создается один раз, будет наблюдать старые объекты. - person mjkdr; 12.01.2019