简体   繁体   中英

Android ROOM - How can I Observe LiveData changes (every time my calendar is set-up) and send the LiveData list results to my adapter?

I have a Custom Calendar .

To create this I have a CalendarFragment which opens CustomCalendarView

(a class which extends LinearLayout).

This then uses MyGridAdapter (class which extends ArrayAdapter) to construct the calendar.

When you click a cell on the calendar, you are taken to a new activity in which you can save a log containing some info (and the date of the cell in the calendar which was clicked). (This loge entry is saved to my database).

I would like to display circles on all of the calendar cells in which a log entry is present.

To do this, I have a method ChangeMonth() in which I pass a list of all visible dates on the calendar to my ViewModel, then I call the setFilter() method which checks the list of visible dates and returns all dates which are present in my logEntry database for that specific month.

How could I observe the resulting list: logEntryDatesFilteredByMonth from my viewModel and then pass this to my adapter so that I can perform the UI changes?

Calendar Fragment

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

CustomCalendarView


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

}

You should implement the observe method like this:

logEntriesViewModel.getDatesFilteredByMonth().observe(this, logDates -> yourAdapter.setData(logDates));

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM