如何在回收者视图中表示父/子结构?

时间:2019-05-16 09:05:32

标签: mvvm android-recyclerview dependencies android-room

我正在努力如何在回收站中显示标准化数据。

我试图用不同的项目类型来代表课程的各个阶段以及这些阶段中的课程,从而代表回收商中培训课程的结构化课程。我已经在MySQL中创建了数据,在AWS上构建了一个简单的asp.net Web服务,以JSON格式提供了培训课程,并成功地从我的Android Studio应用中调用了该服务,为课程,课程的各个阶段和课程创建了对象。我可以通过Room将对象保存到SQLite。但是,我不知道如何最好地将数据绑定到回收站。我最初只是观察这些课程,然后将它们传递给列表适配器(此方法有效),但我也想展示各个阶段。我在网站上查找了示例,但除了可扩展列表和回收站中的回收站外,似乎找不到其他任何东西。因为我知道回收商可以容纳不同类型的物品,所以我怀疑一定缺少一些简单的东西。

片段

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;
}

课程库

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;
}

课程实体

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中访问此列表时遇到了问题;我收到一个致命异常,因为这种方法会导致在主UI线程上调用数据库。

非常感谢所有指导。请不要对我的java-newbie代码过于苛刻!让我知道是否需要将其扩展到任何地方:)

0 个答案:

没有答案