应用程序将片段与“视图模型”模式结合使用。在该片段中,将显示两个Spinners和RecylclerView。其中一个Spinner包含一个工作日,其中包含相应的练习,当更改Spinner的工作日选择时应更新这些练习。因此,我使用Livedata.observe()
方法。在应用程序开始时,将加载当天的所有练习。此外,还将在练习中添加此列表的另一个元素以创建新的练习(我现在将该元素称为“添加练习”)。
当我现在将工作日更改为其他日期时,仅在旋转屏幕后才会更新列表。此外,每次旋转屏幕时,都会添加一个附加的“添加锻炼”项目。基于这种行为,我意识到即使屏幕与Spinner元素没有任何交互,每次旋转屏幕时,Spinner Listener的onItemSelected()
方法也会被激活。
此外,如果更改为另一个片段,所有加载的数据和Spinner元素的选择都将丢失(据我了解,ViewModel,这正是应该借助ViewModel类来防止的)。>
最后,这是我的问题:
从HomeViewModel中提取:
public class HomeViewModel extends ViewModel {
private static final String TAG = "HomeViewModel";
private MutableLiveData<List<Exercise>> mExercises;
private MutableLiveData<List<TrainingPlan>> mTrainingPlans;
private MutableLiveData<Integer> calendarDay;
private TrainingPlan selectedTrainingPlan;
final Exercise addExercise = Exercise.builder().name("ADD EXERCISE").sets(null).build();
private List<TrainingPlan> trainingPlans;
private List<Exercise> currentExercises;
public HomeViewModel() {
mTrainingPlans = new MutableLiveData<>();
mExercises = new MutableLiveData<>();
TrainingsPlanDAO trainingsPlanDAO = new DummyTrainingsPlanDAO();
trainingPlans = trainingsPlanDAO.searchAll();
setSelectedTrainingPlanToDefaultTrainingPlan(trainingPlans);
currentExercises = getExercisesOfTheCurrentDay();
if(currentExercises.isEmpty()){
Log.i(TAG, "No Exercises for the current day!");
}
mTrainingPlans.setValue(trainingPlans);
mExercises.setValue(currentExercises);
//additional Exercise in the list for Add function of new Exercise
currentExercises.add(addExercise);
}
public LiveData<List<Exercise>> getExercises() {
return mExercises;
}
public Integer getCurrentDay(){ return getCalendarDay(); }
public LiveData<List<TrainingPlan>> getTrainingPlans(){ return mTrainingPlans; }
public void setmExercisesToDay(int day){
List<Exercise> exercises = getExercisesOfDay(day);
exercises.add(addExercise);
mExercises.setValue(exercises);
}
private void setSelectedTrainingPlan(TrainingPlan selectedTrainingPlan){
this.selectedTrainingPlan = selectedTrainingPlan;
}...
HomeFragment:
public class HomeFragment extends Fragment {
private HomeViewModel homeViewModel;
private ExerciseRecyclerViewAdapter exerciseAdapter;
private ArrayAdapter<CharSequence> weekdayAdapter;
private ArrayAdapter<TrainingPlan> trainingPlanAdapter;
View root;
@Override
public View onCreateView(@NonNull LayoutInflater inflater,
ViewGroup container, Bundle savedInstanceState) {
homeViewModel =
ViewModelProviders.of(this).get(HomeViewModel.class);
root = inflater.inflate(R.layout.fragment_home, container, false);
initElements();
return root;
}
private void initElements(){
initWeekdaySpinner();
initTrainingPlanSpinner();
initRecylerView();
}
private void initWeekdaySpinner(){
final Spinner currentDaySpinner = root.findViewById(R.id.currentDay_spinner);
currentDaySpinner.setOnItemSelectedListener(countrySelected);
weekdayAdapter = ArrayAdapter.createFromResource(getActivity(), R.array.weekdays, android.R.layout.simple_spinner_item);
weekdayAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
currentDaySpinner.setAdapter(weekdayAdapter);
currentDaySpinner.setSelection(mapWeekdayFromCalenderDayToSpinnerPosition(homeViewModel.getCurrentDay()));
}
private void initTrainingPlanSpinner(){
final Spinner trainingPlanSpinner = root.findViewById(R.id.currentPlan_spinner);
trainingPlanAdapter = new ArrayAdapter<>(getActivity(), android.R.layout.simple_spinner_item, homeViewModel.getTrainingPlans().getValue());
trainingPlanAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
trainingPlanSpinner.setAdapter(trainingPlanAdapter);
}
private void initRecylerView(){
final RecyclerView recyclerView = root.findViewById(R.id.exercise_recyclerView);
homeViewModel.getExercises().observe(this, new Observer<List<Exercise>>() {
@Override
public void onChanged(@Nullable List<Exercise> mExercises) {
exerciseAdapter.notifyDataSetChanged();
}
});
exerciseAdapter = new ExerciseRecyclerViewAdapter(getActivity(), homeViewModel.getExercises().getValue());
RecyclerView.LayoutManager linearLayoutManager = new LinearLayoutManager(this.getContext());
recyclerView.setLayoutManager(linearLayoutManager);
recyclerView.setAdapter(exerciseAdapter);
}
AdapterView.OnItemSelectedListener countrySelected = new AdapterView.OnItemSelectedListener(){
@Override
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
homeViewModel.setmExercisesToDay(mapWeekdayFromSpinnerPositionToCalenderDay(position));
}
@Override
public void onNothingSelected(AdapterView<?> parent) {
}
};
private int mapWeekdayFromCalenderDayToSpinnerPosition(int integer){
return (integer + 5) % 7;
}
private int mapWeekdayFromSpinnerPositionToCalenderDay(int integer){
return (integer + 2) % 7;
}
}