Search code examples
javaandroidandroid-sqliteandroid-roomandroid-calendar

Android ROOM- How can I run a query on each cell inside my custom calendar?


I have a customCalendarView.

To create this I used an ArrayAdapter class (MyGridAdapter).

When a user clicks on a square in the calendar, they are taken to an activity in which they can save a logEntry containing some information along with the date on which was clicked on the calendar.

This log entry is saved to a database.

I would like to display a small circle on each square in the calendar when a log entry is present on that specific day.

I have created a query inside my logEntriesDao which returns all logs with the same date as the date which is passed to it.

@Query("SELECT * FROM log_entries_table WHERE log_entries_table.date = :date " ) LiveData<List<Log_Entries>> getAllFromWorkoutLogEntriesonDate(String date);

How could I run this query on each cell in my calendar and then set my circle imageView visibility to VISIBLE on each calendar cell in which a log is present?

CustomCalendarView

public class CustomCalendarView extends LinearLayout {
    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(("yyyy-MM-dd"),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<Log_Entries> eventsList = 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);
    }

    private void SetUpCalendar(){

        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) -1;
        monthCalendar.add(Calendar.DAY_OF_MONTH, - FirstDayofMonth);

        while (dates.size() < MAX_CALENDAR_DAYS){
            dates.add(monthCalendar.getTime());
            monthCalendar.add(Calendar.DAY_OF_MONTH, 1);
        }
        myGridAdapter = new MyGridAdapter(context,dates,calendar,eventsList);
        gridView.setAdapter(myGridAdapter);

    }
    }


MyGridAdapter

public class MyGridAdapter extends ArrayAdapter {
    List<Date> dates;
    Calendar currentDate;

    List<Log_Entries> logs;

    LayoutInflater inflater;

    public MyGridAdapter(@NonNull Context context, List<Date> dates, Calendar currentDate, List<Log_Entries> logs){
        super(context, R.layout.single_cell_layout);

        this.dates = dates;
        this.currentDate = currentDate;
        this.logs = logs;
        inflater = LayoutInflater.from(context);
    }
    @NonNull
    @Override
    public View getView(int position, @Nullable View convertView, @NonNull ViewGroup parent) {
        Date monthDate = dates.get(position);
        Calendar dateCalendar = Calendar.getInstance();
        dateCalendar.setTime(monthDate);
        int DayNo = dateCalendar.get(Calendar.DAY_OF_MONTH);
        int displayMonth = dateCalendar.get(Calendar.MONTH) +1;
        int displayYear = dateCalendar.get(Calendar.YEAR);
        int currentMonth = currentDate.get(Calendar.MONTH) + 1;
        int currentYear = currentDate.get(Calendar.YEAR);
        int currentDay = currentDate.get(Calendar.DAY_OF_MONTH);

        View view = convertView;
        if (view == null){
            view = inflater.inflate(R.layout.single_cell_layout, parent,false);
        }

        if (displayMonth == currentMonth && displayYear == currentYear){
            view.setBackgroundColor(getContext().getResources().getColor(R.color.green));
        }
        else{
            view.setBackgroundColor(Color.parseColor("#cccccc"));
        }

        TextView Day_Number = view.findViewById(R.id.calendar_day);
        Day_Number.setText(String.valueOf(DayNo));

        Calendar eventCalendar = Calendar.getInstance();

        if(DayNo == currentDay && displayMonth == eventCalendar.get(Calendar.MONTH) + 1 && displayYear == eventCalendar.get(Calendar.YEAR)){
            Day_Number.setTextColor(Color.parseColor("#FFFF33"));
        }
        ArrayList<String> arrayList = new ArrayList<>();
        for (int i = 0; i < logs.size(); i++){
        }
        return view;
    }

    @Override
    public int getCount() {
        return dates.size();
    }

    @Override
    public int getPosition(@Nullable Object item) {
        return dates.indexOf(item);
    }

    @Nullable
    @Override
    public Object getItem(int position) {
        return dates.get(position);
    }
}

LogEntries Entity


@Entity(tableName = "log_entries_table")
public class Log_Entries {


    @PrimaryKey(autoGenerate = true)
    int log_id;

    @ForeignKey(entity = Junction.class, parentColumns = "exercise_workout_id", childColumns = "junction_id")
    private int junction_id;

    @ForeignKey(entity = Junction.class, parentColumns = "workout_id", childColumns = "workout_id")
    private int workout_id;


   double total_weight_lifted;

   int set_number;

   int reps;

    public  String date;

    public Log_Entries(int junction_id, int workout_id, double total_weight_lifted, int set_number, int reps, String date) {
        this.junction_id = junction_id;
        this.workout_id = workout_id;
        this.total_weight_lifted = total_weight_lifted;
        this.set_number = set_number;
        this.reps = reps;
        this.date = date;
    }


    public void setLog_id(int log_id) {
        this.log_id = log_id;
    }

    public int getLog_id() {
        return log_id;
    }


    public int getJunction_id() {
        return junction_id;
    }


    public double getTotal_weight_lifted() {
        return total_weight_lifted;
    }

    public void setTotal_weight_lifted(double total_weight_lifted) {
        this.total_weight_lifted = total_weight_lifted;
    }

    public int getSet_number() {
        return set_number;
    }


    public int getReps() {
        return reps;
    }

    public int getWorkout_id() {
        return workout_id;
    }

    public void setDate(String date) {
        this.date = date;
    }

    public String getDate() {
        return date;
    }

}

Solution

  • Think about next general schema:

    1. Your query request should be one-time shot on all dates visible on your Calendar. Otherwise it's not optimal. I think you can get either date range (for example, 01.05.20..31.05.20) or date's list (01.05,02.05,...,31.05) and set this range (list) as a parameter to your query (list of dates or date1|date2 for range).
    2. You should change your query to get list of dates, where log is present. Let's say you have 6 dates with logs, so your query should return list with 6 dates.
    3. If you're using MVVM pattern, you can observe your LiveData-result from ROOM at your Activity (observing it you'll get list of 6 dates on activity create and 7 dates after you add some log with your second activity).
    4. You can set then your date's list to your adapter and implement there your UI-changes (circles, background whatever).