javaandroidmaterial-designandroid-calendarandroid-json

How do I display events to a specific date and time in a MaterialCalendarView?


I am testing out a sample app where I am trying to achieve displaying time and date to a specific day.Currently, it just plots to the entire month even if the event if for a day. Say if the event if from 9:30am to 10:30am on Jan 5, it will show up for the entire month, rather than just for Jan 5th. Want to achieve something like this:

enter image description here

Currently my app shows it for the whole month, even if its jan 1 or jan 8 event ( here's a screenshot where it wrongly shows up on the week of jan 15 for instance, even if these 2 events belong to 2 different dates):

enter image description here

The code I am testing out, is here : https://github.com/raghunandankavi2010/SamplesAndroid/tree/master/CalendarTest

With the only difference where in the calendar.xml class I added : app:mcv_showOtherDates="all" under <com.prolificinteractive.materialcalendarview.MaterialCalendarView to show a weekly view. Also, in calendarFragment.java class there is a function called : makeJsonObjectRequest , where the StartDate is parsed, I tried parsing the startTime StartTime and EndTime and EndDate to map the event respective to the date, but that didn't do much.

 String EndDate = jsonObject.getString("EndTime");
                Date date = simpleDateFormat.parse(EndDate);

                String title =  jsonObject.getString("Title");

                Log.d("EndDate ",""+date);
                CalendarDay day = CalendarDay.from(date);
                Event event = new Event(date,title);
                cal = Calendar.getInstance();
                cal.setTime(date);
                int month = cal.get(Calendar.DAY_OF_THE_MONTH); 

Any idea how to go about this and update the code so I can display the event respective to the day of the month and within specific time frame (as shown in the outlook screenshot(first screenshot) above), instead of the whole month? (Also, the json class i testjson.json and included in the project assets folder)

Thanks!


Solution

  • The example in the repo filters the events using the months. You need to filter events by calendar day and update listview in onDateSelected to update listview whenever user selects a different date. You should get something like this:

    public class CalendarFragment extends Fragment implements OnDateSelectedListener {
    
    
        private MaterialCalendarView calendarView;
        private HashMap<CalendarDay,List<Event>> map = new HashMap<>();
        private ListView listView;
        private MyAdapter adapter;
    
    
        @Override
        public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
    
            View view = inflater.inflate(R.layout.calendar, container, false);
    
            listView = view.findViewById(R.id.listview);
    
            adapter = new MyAdapter(getActivity(),new ArrayList<Event>());
            listView.setAdapter(adapter);
    
            calendarView =  view.findViewById(R.id.calendarView);
            calendarView.setDateTextAppearance(View.ACCESSIBILITY_LIVE_REGION_ASSERTIVE);
    
            calendarView.setSelectedDate(LocalDate.now());
    
            calendarView.setOnDateChangedListener(this);
    
            makeJsonObjectRequest();
    
            return view;
        }
    
    
    
    
        private void makeJsonObjectRequest() {
    
            String response = loadJSONFromAsset();
            try {
                JSONArray jArray = new JSONArray(response);
                for (int i = 0; i < jArray.length(); i++) {
                    JSONObject jsonObject = jArray.getJSONObject(i);
                    String StartDate = jsonObject.getString("StartDate");
                    LocalDate date = LocalDate.parse(StartDate, DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss",Locale.US));
    
                    String title =  jsonObject.getString("Title");
    
                    Log.d("Date ",""+date);
                    CalendarDay day = CalendarDay.from(date);
                    Event event = new Event(date,title);
    
    
                    if(!map.containsKey(day))
                    {
                        List<Event> events = new ArrayList<>();
                        events.add(event);
                        map.put(day,events);
                    }else
                    {
                        List<Event> events = map.get(day);
                        events.add(event);
                        map.put(day,events);
    
                    }
    
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
    
            // after parsing
            List<Event> event =  map.get(CalendarDay.from(LocalDate.now()));
            if(event!=null && event.size()>0) {
                adapter.addItems(event);
            }else {
                adapter.clear();
            }
    
            //add small dots on event days
            EventDecorator eventDecorator = new EventDecorator(Color.RED, map.keySet());
            calendarView.addDecorator(eventDecorator);
    
    
        }
    
        public String loadJSONFromAsset() {
            String json = null;
            try {
                InputStream is = getActivity().getAssets().open("testjson.json");
                int size = is.available();
                byte[] buffer = new byte[size];
                is.read(buffer);
                is.close();
                json = new String(buffer, "UTF-8");
            } catch (IOException ex) {
                ex.printStackTrace();
                return null;
            }
            return json;
        }
    
        @Override
        public void onDateSelected(@NonNull MaterialCalendarView widget, @NonNull CalendarDay date, boolean selected) {
    
            calendarView.setHeaderTextAppearance(R.style.AppTheme);
    
            List<Event> event =  map.get(date);
            if(event!=null && event.size()>0) {
                adapter.addItems(event);
            }else {
                adapter.clear();
            }
        }
    
    }