Ваша проблема здесь, верно?
public MutableLiveData<ArrayList<CategoryViewModel>> getCategory(){
...
items=categoryDao.loadCategoryItem().getValue(); // returns null
...
}
Это потому, что ваш метод categoryDao.loadCategoryItem () возвращает объект LiveData.Это означает, что вызов метода будет выполнен в потоке backdround.Таким образом, в настоящий момент вы вызываете метод getValue (), но значение равно нулю.
Чтобы избежать этого, вы можете сделать две плохие вещи.
1. Вызовите loadCategoryItem ()ранее, чтобы иметь значения позже при вызове getValue ();
Ваш класс репозитория
public class CategoryRepository {
Livedata<List<CategoryItem>> items; // moved here
...
public void init () {
items=categoryDao.loadCategoryItem();
}
public MutableLiveData<ArrayList<CategoryViewModel>> getCategory(){
ArrayList<CategoryViewModel> arrayList=new ArrayList<>();
List<CategoryItem> currentList = items.getValue();
for(int i=0;i<currentList.size();i++){
...
}
arrayListMutableLiveData.setValue(arrayList);
return arrayListMutableLiveData;
}
}
Ваш класс ViewModel
public class CategoryViewModel extends AndroidViewModel {
public void init(CategoryItem categoryItem){
repository.init(); // added
this.title=categoryItem.getTitle();
this.imagePath=categoryItem.getImagePath();
}
Это может работать, но у нас есть 2 проблемы,Во-первых, все еще нет гарантии, что значения не будут нулевыми.Вторая проблема заключается в том, что вы не можете наблюдать за изменениями вашего предмета.Даже если вы возвращаете объект arrayListMutableLiveData, который является livingata, вы устанавливаете его значение один раз вручную, и его значение не изменится, пока вы не вызовете getCategory () снова.
2. Secondвзломать элементы категории загрузки async
public interface CategoryDao {
@Query("SELECT * FROM category_table") LiveData<List<CategoryItem>>loadCategoryItem();
@Query("SELECT * FROM category_table") List<CategoryItem> loadCategoryItemsAsync();
В этом случае ваши методы getAllCategories () и getCategory () также должны работать асинхронно.
Примерно так:
public void getCategory(Listener listener){
executor.execute(() -> {
ArrayList<CategoryViewModel> arrayList=new ArrayList<>();
List<CategoryItem> currentList = items.getValue();
for(int i=0;i<currentList.size();i++){
...
}
arrayListMutableLiveData.setValue(arrayList);
listener.onItemsLoaded(arrayListMutableLiveData);
}
}
В этом случае у нас также есть вторая проблема -> вы не можете наблюдать изменения вашего предмета.
Я написал это, чтобы лучше прояснить проблему.*
Реальная проблема заключается в том, что вы пытаетесь использовать CategoryViewModel для привязки данных.
Пожалуйста, используйте взамен CategoryItem
Я предлагаю удалить эти две строки изviewModel
private String title;
private String imagePath;
Попробуйте решить вашу проблему без анализа данных от List до ArrayList.
public LiveData<List<CategoryItem>> getAllCategories(){
if (items == null) {
items = categoryDao.loadCategoryItem()
}
return items;
}
, затем попробуйте использовать CategoryItem в качестве объекта данных
<data class="CategoryDataBinding">
<variable
name="category"
type="com.struct.red.alltolearn.///.CategoryItem "/>
</data>
и попробуйте изменить свой адаптер, чтобы сделать это возможным
categoryViewModel = ViewModelProviders.of(this).get(CategoryViewModel.class);
categoryViewModel.getAllCategories().observe(this, new Observer<List<CategoryItem >>() {
@Override
public void onChanged(@Nullable List<CategoryItem > categoryItems) {
categoryAdapter = new CategoryAdapter(getContext(), categoryItems);
...