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