Я борюсь с тем, как представить нормализованные данные в утилизаторе.
Я пытаюсь представить структурированные уроки учебного курса в переработчике, используя различные типы предметов, чтобы представить фазы курса и уроки в этих фазах. Я создал данные в MySQL, создал простой веб-сервис asp.net на AWS для обслуживания учебных курсов в формате JSON и успешно вызвал сервис из моего приложения для студии Android, создавая объекты для курса, его этапов и уроков. Я могу сохранить этот объект в SQLite через Room. Однако я не знаю, как лучше связать данные с переработчиком. Изначально я только наблюдал уроки и передавал их в список Адаптер (это сработало), но я также хочу показать фазы. Я искал примеры на сайте, но не могу найти ничего, кроме расширяемых списков и утилизаторов внутри утилизаторов. Поскольку я знаю, что переработчики могут хранить различные типы предметов, я подозреваю, что должно быть что-то простое, что мне не хватает.
Фрагмент
public class LessonsFragment extends Fragment {
RecyclerView lstLessons;
RecyclerView.LayoutManager mLayoutManager;
private ListItemAdapter mAdapter;
@Override
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
lstLessons = getView().findViewById(R.id.lstLessons);
}
Public void onActivityCreated(@NullableBundlesavedInstanceState){
super.onActivityCreated(savedInstanceState);
mLayoutManager = new LinearLayoutManager(getContext());
lstLessons.setLayoutManager(mLayoutManager);
mAdapter = new ListItemAdapter();
viewModel=ViewModelProviders.of(this).get(MainViewModel.class);
viewModel.getCourse().observe(this,newObserver<Course>(){
@Override
Public void onChanged(Course course){
}
});
viewModel.getListItems().observe(this,newObserver<List<ListItem>>(){
@Override
publicvoidonChanged(List<ListItem>listItems){
mAdapter.setListItems(listItems);
mAdapter.notifyDataSetChanged();
}
});
}
}
MainViewModel
Public LiveData<Course> getCourse(){
return courseRepository.GetCourse()
}
Public LiveData<List<ListItem>> getListItems(){
listItems=courseRepository.getListItems();
Return listItems;
}
CourseRepository
Public LiveData<Course> GetCourse(){
If (//not up to date){
//Make retrofit call
Course newCourse = response.body;
new DeleteCourseAysyncTask(courseDao, phaseDao, lessonDao).execute();
new InsertCourseAysyncTask(courseDao, phaseDao, lessonDao).execute(newCourse);
}
return courseDao.get();
}
}
public LiveData<List<ListItem>> getListItems(){
return listItems;
}
//Async tasks for delete and insert + ...
//This is the code that can't work since it:
// 1) gets null results for phases and lesson
// 2) doesn't update the LiveData
private static class GetListItemAsyncTask extends AsyncTask<Void, Void, Void>{
private TrainingCourseDao trainingCourseDao;
private PhaseDao phaseDao;
private LessonDao lessonDao;
private GetListItemAsyncTask(TrainingCourseDao trainingCourseDao, PhaseDao phaseDao, LessonDao lessonDao){
this.trainingCourseDao = trainingCourseDao;
this.phaseDao= phaseDao;
this.lessonDao = lessonDao;
}
@Override
protected Void doInBackground(Void... voids) {
listItems.clear();
if (phaseDao.getAll().getValue() != null) {
for (Phase phase : phaseDao.getAll().getValue()) {
listItems.add(new ListItem(ListItem.eItemType.PHASE, phase, phase.getName()));
if (lessonDao.getAll().getValue() != null) {
for (Lesson lesson : lessonDao.getAll().getValue()) {
listItems.add(new ListItem(ListItem.eItemType.LESSON, lesson, lesson.getName()));
}
}
}
}
this.listItems = (LiveData<List<ListItem>>) listItems;
return null;
}
}
}
Курс Дао
@Dao
Public interface CourseDao {
@Insert
Void insert(Course course);
@Delete
Void delete(Course course);
//There's actually a "delete all" too but I'll spare you the query
}
Фаза Дао
@Dao
Public interface PhaseDao {
@Insert
Void insert(Phase… phase);
@Delete
Void delete(Phase phase);
}
Урок Дао
@Dao
Public interface LessonDao {
@Insert
Void insert(Lesson… lesson);
@Delete
Void delete(Lesson lesson);
}
База данных
@Database (entities = {Course.class, Phase.class, Lesson.class}, version=1, exportSchema=false)
public abstract class CourseDatabase extends RoomDatabase{
private static CourseDatabase instance;
public abstract CourseDao courseDao();
public abstract PhaseDao phaseDao();
public abstract LessonDao lessonDao();
public static synchronized CourseDatabase getInstance(Contextcontext){
if(instance==null){
instance=Room.databaseBuilder(context.getApplicationContext(),
CourseDatabase.class, "course_database")
.fallbackToDestructiveMigration()
.addCallback(roomCallback)
.build();
}
return instance;
}
Курс Entity
private String name;
private String description;
@ignore
private List<Phase> phases;
//public constructor, getters and setters
Фаза сущности
private int courseId;
private String name;
private int sequence;
@ignore
Private List<Lesson> lessons;
//public constructor, getters and setters
Организация урока
private int phaseId
private String name;
private String activities;
private int sequence;
//public constructor, getters and setters
Элемент списка
public enum eItemType{
PHASE, LESSON //+there will be others
}
private eItemType mItemType;
private Object mObject;
//public constructor, getters and setters
Я попытался создать общий класс ListItem, который может содержать указатель на мой объект фазы ИЛИ урока, затем создать List и построить список при получении курса, но у меня возникают проблемы при попытке доступа к этому списку в ViewModel; Я получаю фатальное исключение, так как этот подход приводит к вызовам базы данных в главном потоке пользовательского интерфейса.
Все указания очень ценятся. Пожалуйста, не будьте слишком резкими в моем коде java-newbie! и дайте мне знать, если мне нужно расширить его в любом месте:)