Android ROOM - 我如何观察 LiveData 变化(每次设置我的日历时)并将 LiveData 列表结果发送到我的适配器?
Android ROOM - How can I Observe LiveData changes (every time my calendar is set-up) and send the LiveData list results to my adapter?
我有一个Custom Calendar。
为了创建这个,我有一个 CalendarFragment
打开 CustomCalendarView
(扩展 LinearLayout 的 class)。
然后使用 MyGridAdapter
(扩展 ArrayAdapter 的class)构造日历。
当您单击日历上的一个单元格时,您将被带到一个新的 activity,您可以在其中保存包含一些信息的日志(以及日历中被单击的单元格的日期)。
(此日志条目已保存到我的数据库中)。
我想在所有存在日志条目的日历单元格上显示圆圈。
为此,我有一个方法 ChangeMonth(),在该方法中我将日历上所有可见日期的列表传递给我的 ViewModel,然后我调用 setFilter() 方法来检查可见日期列表和 returns 我的 logEntry 数据库中存在的特定月份的所有日期。
我如何从我的 viewModel 观察结果列表:logEntryDatesFilteredByMonth,然后将其传递给我的适配器以便我可以执行 UI 更改?
日历片段
public class CalendarFragment extends Fragment {
CustomCalendarView customCalendarView;
List<LogDates> dates = new ArrayList<>();
LogEntriesViewModel logEntriesViewModel;
MyGridAdapter myGridAdapter;
@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
return inflater.inflate(R.layout.calendar_activity_main, container, false);
}
@Override
public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
customCalendarView = (CustomCalendarView) getView().findViewById(R.id.custom_calendar_view);
((AppCompatActivity) getActivity()).getSupportActionBar().hide();
customCalendarView.SetUpCalendar();
logEntriesViewModel.getDatesFilteredByMonth().observe(this, logDates -> myGridAdapter.setData(logDates));
Log.i("PRESENT_DATES", String.valueOf(dates));
}
}
自定义日历视图
public class CustomCalendarView extends LinearLayout {
private LogEntriesViewModel logEntriesViewModel;
ImageButton NextButton, PreviousButton;
TextView CurrentDate;
GridView gridView;
public static final int MAX_CALENDAR_DAYS = 42;
Calendar calendar = Calendar.getInstance(Locale.ENGLISH);
Context context;
MyGridAdapter myGridAdapter;
SimpleDateFormat dateFormat = new SimpleDateFormat("MMMM yyyy", Locale.ENGLISH);
SimpleDateFormat monthFormat = new SimpleDateFormat("MMMM", Locale.ENGLISH);
SimpleDateFormat yearFormat = new SimpleDateFormat("yyyy", Locale.ENGLISH);
SimpleDateFormat eventDateFormat = new SimpleDateFormat(("dd-MM-yyyy"), Locale.ENGLISH);
public static final String MY_PREFS_NAME = "MyPrefsFile";
List<Date> dates = new ArrayList<>();
List<LogDates> logsList = new ArrayList<>();
List<String> datesFormattedList = new ArrayList<>();
public CustomCalendarView(Context context) {
super(context);
}
public CustomCalendarView(final Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
this.context = context;
InitializeLayout();
SetUpCalendar();
PreviousButton.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
calendar.add(Calendar.MONTH, -1);
SetUpCalendar();
}
});
NextButton.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
calendar.add(Calendar.MONTH, 1);
SetUpCalendar();
}
});
gridView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
AlertDialog.Builder builder = new AlertDialog.Builder(context);
builder.setCancelable(true);
final String date = eventDateFormat.format(dates.get(position));
Intent i = new Intent(getContext(), WorkoutButtonsActivity.class);
i.putExtra(WorkoutButtonsActivity.EXTRA_DATE, date);
getContext().startActivity(i);
}
});
}
public CustomCalendarView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
private void InitializeLayout() {
LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View view = inflater.inflate(R.layout.calendar_layout, this);
NextButton = view.findViewById(R.id.nextBtn);
PreviousButton = view.findViewById(R.id.previousBtn);
CurrentDate = view.findViewById(R.id.current_Date);
gridView = view.findViewById(R.id.gridview);
}
void SetUpCalendar() {
datesFormattedList.clear();
String currentDate = dateFormat.format(calendar.getTime());
CurrentDate.setText(currentDate);
dates.clear();
Calendar monthCalendar = (Calendar) calendar.clone();
monthCalendar.set(Calendar.DAY_OF_MONTH, 1);
int FirstDayofMonth = monthCalendar.get(Calendar.DAY_OF_WEEK) - 2;
monthCalendar.add(Calendar.DAY_OF_MONTH, -FirstDayofMonth);
while (dates.size() < MAX_CALENDAR_DAYS) {
dates.add(monthCalendar.getTime());
monthCalendar.add(Calendar.DAY_OF_MONTH, 1);
}
/*THIS CONVERTS THE LIST OF ALL VISIBLE DATES TO A STRING */
for (int i = 0; i< MAX_CALENDAR_DAYS; i++) {
final String dateFormatted = eventDateFormat.format(dates.get(i));
datesFormattedList.add(dateFormatted);
}
Log.i("Dates", String.valueOf(datesFormattedList));
ChangeMonth();
myGridAdapter = new MyGridAdapter(context, dates, calendar, logsList);
gridView.setAdapter(myGridAdapter);
}
public void ChangeMonth() {
logEntriesViewModel = ViewModelProviders.of((FragmentActivity) context).get(LogEntriesViewModel.class);
logEntriesViewModel.setFilter(datesFormattedList);
}
}
LogEntries ViewModel
public class LogEntriesViewModel extends AndroidViewModel {
private LogEntriesRepository repository;
// private LiveData<List<Log_Entries>> allLogEntries;
private LiveData<List<Log_Entries>> allWorkoutLogEntries;
private LiveData<List<LogDates>> logEntryDatesFilteredByMonth;
private LiveData<List<LogDates>> allLogEntryDates;
private MutableLiveData<List<String>> filterLogPresentDates = new MutableLiveData <List<String>>();
public LogEntriesViewModel(@NonNull Application application) {
super(application);
repository = new LogEntriesRepository(application);
allLogEntryDates = repository.getAllLogEntryDates();
logEntryDatesFilteredByMonth = Transformations.switchMap(filterLogPresentDates, c -> repository.getAllDateLogEntries(c));
}
public LiveData<List<LogDates>> getDatesFilteredByMonth() { return logEntryDatesFilteredByMonth; }
public void setFilter(List<String> currentMonthDates) { filterLogPresentDates.setValue(currentMonthDates); }
LiveData<List<LogDates>> getAllLogEntryDates() { return allLogEntryDates; }
public void insert(Log_Entries log_entries){
repository.insert(log_entries);
}
public void update(Log_Entries log_entries){
repository.update(log_entries);
}
public void delete(Log_Entries log_entries ) {
repository.delete(log_entries);
}
public LiveData<List<Log_Entries>> getAllWorkoutLogEntries(int junctionID, String date){
allWorkoutLogEntries = repository.getAllWorkoutLogEntries(junctionID, date);
return allWorkoutLogEntries;
}
}
LogEntries DAO
@Dao
public interface Log_Entries_Dao {
@Insert
void insert(Log_Entries logEntry);
@Update
void update(Log_Entries logEntry);
@Delete
void delete(Log_Entries logEntry);
@Query("SELECT * FROM log_entries_table")
LiveData<List<Log_Entries>> getAllFromLogEntries();
@Query("SELECT * FROM log_entries_table WHERE log_entries_table.junction_id = :junctionID AND log_entries_table.date = :date " )
LiveData<List<Log_Entries>> getAllFromWorkoutLogEntries(int junctionID, String date);
@Query("SELECT * FROM log_entries_table WHERE log_entries_table.date = :date " )
LiveData<List<Log_Entries>> getAllDatesWithLogEntries(String date);
@Query("SELECT date FROM log_entries_table WHERE log_entries_table.date = :date " )
LiveData<List<LogDates>> getAllDatesWithLogs(List<String> date);
@Query("SELECT date FROM log_entries_table " )
LiveData<List<LogDates>> getAllLogEntryDates();
}
你应该像这样实现观察方法:
logEntriesViewModel.getDatesFilteredByMonth().observe(this, logDates -> yourAdapter.setData(logDates));
我有一个Custom Calendar。
为了创建这个,我有一个 CalendarFragment
打开 CustomCalendarView
(扩展 LinearLayout 的 class)。
然后使用 MyGridAdapter
(扩展 ArrayAdapter 的class)构造日历。
当您单击日历上的一个单元格时,您将被带到一个新的 activity,您可以在其中保存包含一些信息的日志(以及日历中被单击的单元格的日期)。 (此日志条目已保存到我的数据库中)。
我想在所有存在日志条目的日历单元格上显示圆圈。
为此,我有一个方法 ChangeMonth(),在该方法中我将日历上所有可见日期的列表传递给我的 ViewModel,然后我调用 setFilter() 方法来检查可见日期列表和 returns 我的 logEntry 数据库中存在的特定月份的所有日期。
我如何从我的 viewModel 观察结果列表:logEntryDatesFilteredByMonth,然后将其传递给我的适配器以便我可以执行 UI 更改?
日历片段
public class CalendarFragment extends Fragment {
CustomCalendarView customCalendarView;
List<LogDates> dates = new ArrayList<>();
LogEntriesViewModel logEntriesViewModel;
MyGridAdapter myGridAdapter;
@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
return inflater.inflate(R.layout.calendar_activity_main, container, false);
}
@Override
public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
customCalendarView = (CustomCalendarView) getView().findViewById(R.id.custom_calendar_view);
((AppCompatActivity) getActivity()).getSupportActionBar().hide();
customCalendarView.SetUpCalendar();
logEntriesViewModel.getDatesFilteredByMonth().observe(this, logDates -> myGridAdapter.setData(logDates));
Log.i("PRESENT_DATES", String.valueOf(dates));
}
}
自定义日历视图
public class CustomCalendarView extends LinearLayout {
private LogEntriesViewModel logEntriesViewModel;
ImageButton NextButton, PreviousButton;
TextView CurrentDate;
GridView gridView;
public static final int MAX_CALENDAR_DAYS = 42;
Calendar calendar = Calendar.getInstance(Locale.ENGLISH);
Context context;
MyGridAdapter myGridAdapter;
SimpleDateFormat dateFormat = new SimpleDateFormat("MMMM yyyy", Locale.ENGLISH);
SimpleDateFormat monthFormat = new SimpleDateFormat("MMMM", Locale.ENGLISH);
SimpleDateFormat yearFormat = new SimpleDateFormat("yyyy", Locale.ENGLISH);
SimpleDateFormat eventDateFormat = new SimpleDateFormat(("dd-MM-yyyy"), Locale.ENGLISH);
public static final String MY_PREFS_NAME = "MyPrefsFile";
List<Date> dates = new ArrayList<>();
List<LogDates> logsList = new ArrayList<>();
List<String> datesFormattedList = new ArrayList<>();
public CustomCalendarView(Context context) {
super(context);
}
public CustomCalendarView(final Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
this.context = context;
InitializeLayout();
SetUpCalendar();
PreviousButton.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
calendar.add(Calendar.MONTH, -1);
SetUpCalendar();
}
});
NextButton.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
calendar.add(Calendar.MONTH, 1);
SetUpCalendar();
}
});
gridView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
AlertDialog.Builder builder = new AlertDialog.Builder(context);
builder.setCancelable(true);
final String date = eventDateFormat.format(dates.get(position));
Intent i = new Intent(getContext(), WorkoutButtonsActivity.class);
i.putExtra(WorkoutButtonsActivity.EXTRA_DATE, date);
getContext().startActivity(i);
}
});
}
public CustomCalendarView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
private void InitializeLayout() {
LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View view = inflater.inflate(R.layout.calendar_layout, this);
NextButton = view.findViewById(R.id.nextBtn);
PreviousButton = view.findViewById(R.id.previousBtn);
CurrentDate = view.findViewById(R.id.current_Date);
gridView = view.findViewById(R.id.gridview);
}
void SetUpCalendar() {
datesFormattedList.clear();
String currentDate = dateFormat.format(calendar.getTime());
CurrentDate.setText(currentDate);
dates.clear();
Calendar monthCalendar = (Calendar) calendar.clone();
monthCalendar.set(Calendar.DAY_OF_MONTH, 1);
int FirstDayofMonth = monthCalendar.get(Calendar.DAY_OF_WEEK) - 2;
monthCalendar.add(Calendar.DAY_OF_MONTH, -FirstDayofMonth);
while (dates.size() < MAX_CALENDAR_DAYS) {
dates.add(monthCalendar.getTime());
monthCalendar.add(Calendar.DAY_OF_MONTH, 1);
}
/*THIS CONVERTS THE LIST OF ALL VISIBLE DATES TO A STRING */
for (int i = 0; i< MAX_CALENDAR_DAYS; i++) {
final String dateFormatted = eventDateFormat.format(dates.get(i));
datesFormattedList.add(dateFormatted);
}
Log.i("Dates", String.valueOf(datesFormattedList));
ChangeMonth();
myGridAdapter = new MyGridAdapter(context, dates, calendar, logsList);
gridView.setAdapter(myGridAdapter);
}
public void ChangeMonth() {
logEntriesViewModel = ViewModelProviders.of((FragmentActivity) context).get(LogEntriesViewModel.class);
logEntriesViewModel.setFilter(datesFormattedList);
}
}
LogEntries ViewModel
public class LogEntriesViewModel extends AndroidViewModel {
private LogEntriesRepository repository;
// private LiveData<List<Log_Entries>> allLogEntries;
private LiveData<List<Log_Entries>> allWorkoutLogEntries;
private LiveData<List<LogDates>> logEntryDatesFilteredByMonth;
private LiveData<List<LogDates>> allLogEntryDates;
private MutableLiveData<List<String>> filterLogPresentDates = new MutableLiveData <List<String>>();
public LogEntriesViewModel(@NonNull Application application) {
super(application);
repository = new LogEntriesRepository(application);
allLogEntryDates = repository.getAllLogEntryDates();
logEntryDatesFilteredByMonth = Transformations.switchMap(filterLogPresentDates, c -> repository.getAllDateLogEntries(c));
}
public LiveData<List<LogDates>> getDatesFilteredByMonth() { return logEntryDatesFilteredByMonth; }
public void setFilter(List<String> currentMonthDates) { filterLogPresentDates.setValue(currentMonthDates); }
LiveData<List<LogDates>> getAllLogEntryDates() { return allLogEntryDates; }
public void insert(Log_Entries log_entries){
repository.insert(log_entries);
}
public void update(Log_Entries log_entries){
repository.update(log_entries);
}
public void delete(Log_Entries log_entries ) {
repository.delete(log_entries);
}
public LiveData<List<Log_Entries>> getAllWorkoutLogEntries(int junctionID, String date){
allWorkoutLogEntries = repository.getAllWorkoutLogEntries(junctionID, date);
return allWorkoutLogEntries;
}
}
LogEntries DAO
@Dao
public interface Log_Entries_Dao {
@Insert
void insert(Log_Entries logEntry);
@Update
void update(Log_Entries logEntry);
@Delete
void delete(Log_Entries logEntry);
@Query("SELECT * FROM log_entries_table")
LiveData<List<Log_Entries>> getAllFromLogEntries();
@Query("SELECT * FROM log_entries_table WHERE log_entries_table.junction_id = :junctionID AND log_entries_table.date = :date " )
LiveData<List<Log_Entries>> getAllFromWorkoutLogEntries(int junctionID, String date);
@Query("SELECT * FROM log_entries_table WHERE log_entries_table.date = :date " )
LiveData<List<Log_Entries>> getAllDatesWithLogEntries(String date);
@Query("SELECT date FROM log_entries_table WHERE log_entries_table.date = :date " )
LiveData<List<LogDates>> getAllDatesWithLogs(List<String> date);
@Query("SELECT date FROM log_entries_table " )
LiveData<List<LogDates>> getAllLogEntryDates();
}
你应该像这样实现观察方法:
logEntriesViewModel.getDatesFilteredByMonth().observe(this, logDates -> yourAdapter.setData(logDates));