Display the List of Events Within the Calendar?

15,458

Solution 1

You need to add a DotSpan. Also i had to read the library docs cause i haven't used this myself.

Step 1: In your Fragment class

 private List<CalendarDay> events = new ArrayList<>();

Step 2 :

private void makeJsonObjectRequest() {


    SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss", Locale.getDefault());

    // i copied your json to load form assets folder
    // in our case you can get the json from the server
    // or any other location of your choice
    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");
            Date date = simpleDateFormat.parse(StartDate);

            Log.d("Date ",""+date);
            CalendarDay day = CalendarDay.from(date);
            events.add(day);
        }
    } catch (Exception e) {
        e.printStackTrace();
    }

    EventDecorator eventDecorator = new EventDecorator(Color.RED, events);
    calendarView.addDecorator(eventDecorator);

}

Step 3: Change your EventDecorator class

public class EventDecorator implements DayViewDecorator {

private int color;
private HashSet<CalendarDay> dates;

public EventDecorator(int color, Collection<CalendarDay> dates) {
    this.color = color;
    this.dates = new HashSet<>(dates);
}

@Override
public boolean shouldDecorate(CalendarDay day) {
    return dates.contains(day);
}

@Override
public void decorate(DayViewFacade view) {
    view.addSpan(new DotSpan(5, color));
}
}

You can look at the DotSpan and customize it your self. Its a LinearBackgroundSpan

Screen shot on my emulator

enter image description here

Edit:

And specific month should list specific month event rather than all the event ,which is the one i am getting on Currently.

You need to check the month that is currently displayed and make sure you sync your listview to display events accordingly.Clear the list data that is used to display events in list based on the month the calendar displays and refresh your list.

Or you could just display the events for the day on click of date.

How you do it is left to you. You can have a look at this https://github.com/memfis19/Cadar library which should give an insight or help you modify your code accordingly. Based on the month displayed the list displays events.

Edit 2:

My Adapter class

public class MyAdapter extends ArrayAdapter<Event> {

    private  List<Event> list;
    private LayoutInflater mInflater;

    public MyAdapter(Context context, List<Event> list) {
        super(context, R.layout.row, list);
        this.mInflater = LayoutInflater.from(context);
        this.list = list;
    }

    static class ViewHolder {
         TextView text;

    }

    public void addItems(List<Event> list) {
        this.list.clear();
        this.list.addAll(list);
        notifyDataSetChanged();

    }


    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        ViewHolder viewHolder;

        if (convertView == null) {

            convertView = mInflater.inflate(R.layout.row, parent,false);
            viewHolder = new ViewHolder();
            viewHolder.text = (TextView) convertView.findViewById(R.id.label);

            convertView.setTag(viewHolder);
        } else {
            viewHolder = (ViewHolder) convertView.getTag();
        }

        viewHolder.text.setText(list.get(position).getEvents());

        return convertView;
    }   
}

My CalendarFragment

public class CalendarFragment extends Fragment implements OnMonthChangedListener {


    private MaterialCalendarView calendarView;
    private List<CalendarDay> calevents = new ArrayList<>();
    private List<Event> eventList = new ArrayList<>();
    private HashMap<Integer,List<Event>> map = new HashMap<>();
    private ListView listView;
    private MyAdapter adapter;
    private Calendar cal;


    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {

        View view = inflater.inflate(R.layout.calendar, container, false);

        listView = (ListView)view.findViewById(R.id.listview);

        adapter = new MyAdapter(getActivity(),eventList);
        listView.setAdapter(adapter);

        calendarView =  view.findViewById(R.id.calendarView);
        calendarView.setDateTextAppearance(View.ACCESSIBILITY_LIVE_REGION_ASSERTIVE);
        final Calendar calendar = Calendar.getInstance();
        calendarView.setSelectedDate(calendar.getTime());
        calendarView.setOnDateChangedListener(new OnDateSelectedListener() {
            @Override
            public void onDateSelected(@NonNull MaterialCalendarView widget, @NonNull CalendarDay date, boolean selected) {
                calendarView.setHeaderTextAppearance(R.style.AppTheme);
            }
        });



        calendarView.setOnMonthChangedListener(this);

        makeJsonObjectRequest();

        return view;
    }




    private void makeJsonObjectRequest() {


        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss", Locale.getDefault());

        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");
                Date date = simpleDateFormat.parse(StartDate);

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

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

                if(!map.containsKey(month))
                {
                    List<Event> events = new ArrayList<>();
                    events.add(event);
                    map.put(month,events);
                }else
                {
                    List<Event> events = map.get(month);
                    events.add(event);
                    map.put(month,events);

                }

                calevents.add(day);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }

        // after parsing
        cal = Calendar.getInstance();
        int month = cal.get(Calendar.MONTH);
        List<Event> event =  map.get(month);
        adapter.addItems(event);
        EventDecorator eventDecorator = new EventDecorator(Color.RED, calevents);
        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 onMonthChanged(MaterialCalendarView widget, CalendarDay date) {
        Calendar cal = Calendar.getInstance();
        cal.setTime(date.getDate());
        int month = cal.get(Calendar.MONTH);
        List<Event> event =  map.get(month);
        adapter.addItems(event);

    }
}

Solution 2

You will need an EventDecorator class like

public class EventDecorator implements DayViewDecorator {

    private int color;
    private HashSet<CalendarDay> dates;

    public EventDecorator(int color, Collection<CalendarDay> dates) {
        this.color = color;
        this.dates = new HashSet<>(dates);
    }

    @Override
    public boolean shouldDecorate(CalendarDay day) {
        return dates.contains(day);
    }

    @Override
    public void decorate(DayViewFacade view) {
        view.addSpan(new DotSpan(5, color));
    }
}

Then on the main acitvity/fragment u need to make use of an sync tasks that get json data and set the events in calendar like this sample.

/**
 * Shows off the most basic usage
 */
public class BasicActivityDecorated extends AppCompatActivity implements OnDateSelectedListener {

    private final OneDayDecorator oneDayDecorator = new OneDayDecorator();

    @BindView(R.id.calendarView)
    MaterialCalendarView widget;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_basic);
        ButterKnife.bind(this);

        widget.setOnDateChangedListener(this);
        widget.setShowOtherDates(MaterialCalendarView.SHOW_ALL);

        Calendar instance = Calendar.getInstance();
        widget.setSelectedDate(instance.getTime());

        Calendar instance1 = Calendar.getInstance();
        instance1.set(instance1.get(Calendar.YEAR), Calendar.JANUARY, 1);

        Calendar instance2 = Calendar.getInstance();
        instance2.set(instance2.get(Calendar.YEAR), Calendar.DECEMBER, 31);

        widget.state().edit()
                .setMinimumDate(instance1.getTime())
                .setMaximumDate(instance2.getTime())
                .commit();

        widget.addDecorators(
                new MySelectorDecorator(this),
                new HighlightWeekendsDecorator(),
                oneDayDecorator
        );

        new ApiSimulator().executeOnExecutor(Executors.newSingleThreadExecutor());
    }

    @Override
    public void onDateSelected(@NonNull MaterialCalendarView widget, @NonNull CalendarDay date, boolean selected) {
        //If you change a decorate, you need to invalidate decorators
        oneDayDecorator.setDate(date.getDate());
        widget.invalidateDecorators();
    }

    /**
     * Simulate an API call to show how to add decorators
     */
    private class ApiSimulator extends AsyncTask<Void, Void, List<CalendarDay>> {

        @Override
        protected List<CalendarDay> doInBackground(@NonNull Void... voids) {
            try {
                Thread.sleep(2000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            Calendar calendar = Calendar.getInstance();
            calendar.add(Calendar.MONTH, -2);
            ArrayList<CalendarDay> dates = new ArrayList<>();
            for (int i = 0; i < 30; i++) {
                CalendarDay day = CalendarDay.from(calendar);
                dates.add(day);
                calendar.add(Calendar.DATE, 5);
            }

            return dates;
        }

        @Override
        protected void onPostExecute(@NonNull List<CalendarDay> calendarDays) {
            super.onPostExecute(calendarDays);

            if (isFinishing()) {
                return;
            }

            widget.addDecorator(new EventDecorator(Color.RED, calendarDays));
        }
    }
}

U need to mode this class to include an api call and use that response to bind the dates to calendar. Hope this will help!

Solution 3

I am assuming that you want to display the list of events within a month-type calendar. ZCustomCalendar allows you to make custom views for different types of dates. Within that custom view you can define a ListView and then maybe display the list of events in that.

Share:
15,458
seon
Author by

seon

There is always hope.

Updated on June 04, 2022

Comments

  • seon
    seon about 2 years

    I am able to Display the Events Within the List below the Calendar but i want to Display the Events Within the Calendar through the JSON Data.I have used CalendarView for Showing the Calendar.I have watched this but not able to solve what i exactly Wanted.

    xml

      <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:app="http://schemas.android.com/apk/res-auto"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical">
    
    
        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:background="#2E353D"
            android:orientation="vertical">
    
            <LinearLayout
                android:layout_width="wrap_content"
                android:layout_height="40dp"
                android:layout_gravity="center_horizontal"
                android:orientation="horizontal">
    
                <ImageView
                    android:layout_width="30dp"
                    android:layout_height="match_parent"
                    android:padding="3dp"
                    android:src="@mipmap/calander" />
    
                <TextView
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:layout_gravity="center_vertical"
                    android:layout_marginLeft="8dp"
                    android:text="Calendar"
                    android:textColor="#fff"
                    android:textSize="17dp"
                    android:textStyle="bold" />
    
            </LinearLayout>
        </LinearLayout>
    
    
          <com.prolificinteractive.materialcalendarview.MaterialCalendarView
                android:id="@+id/calendar"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_centerInParent="true" />
    
    
        <!--  <CalendarView
            android:id="@+id/calendar"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_centerInParent="true" />     -->
    
    
        <ListView
            android:id="@+id/calenderlist"
            android:layout_width="match_parent"
            android:layout_height="wrap_content" />
    
    
    </LinearLayout>
    

    CalenderFragment

      public class CalenderFragment extends Fragment implements OnMonthChangedListener {
        String Navigation_URL = "http://192.168.100.5:84/api/academics/getEvents";
        String access_token;
        ListView listView;
        com.prolificinteractive.materialcalendarview.MaterialCalendarView calendarView;
        ArrayList<CalenderPojoStudent> student_list_calender = new ArrayList<>();
    
        private HashMap<Integer, List<Event>> map = new HashMap<>();
        private List<CalendarDay> calevents = new ArrayList<>();
    
        private Calendar cal;
        private List<Event> eventList = new ArrayList<>();
    
    
        private MyAdapterCalendar adapter;
    
        private SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd", Locale.getDefault());
    
        @Override
        public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
            View view = inflater.inflate(R.layout.calender, container, false);
            getActivity().setTitle("");
            setHasOptionsMenu(true);
    
            calendarView = (com.prolificinteractive.materialcalendarview.MaterialCalendarView) view.findViewById(R.id.calendar);
            final Calendar calendar = Calendar.getInstance();
            calendarView.setSelectedDate(calendar.getTime());
            calendarView.setSelectedDate(calendar.getTime());
    
    
            listView = (ListView) view.findViewById(R.id.calenderlist);
            adapter = new MyAdapterCalendar(getActivity(), eventList);
           // listView.setAdapter(adapter);
    
            //  calendarView.addDecorator(new HighlightWeekendsDecorator());
            calendarView.addDecorator(new OneDayDecorator());
            // calendarView.addDecorator(new EventDecorator(Color.RED, calendarDays));
            // calendarView.addView(onMonthChanged(calendarView,date));
            // calendarView.addDecorator(new EventDecorator(Color.RED, calendarDays));
            //calendarView.addDecorator(new MySelectorDecorator(getActivity()));
    
    
            // calendarView.addDecorator(new EventDecorator("#FF0000",student_list_calender));
            //  calendarView.addDecorator(new EventDecorator("",));
            //calendarView.setDateTextAppearance(View.ACCESSIBILITY_LIVE_REGION_ASSERTIVE);
    
    
            SessionManagement session = new SessionManagement(getContext());
            session.checkLogin();
            access_token = session.getAccesstToken();
            makeJsonObjectRequest();
    
    
            return view;
        }
    
        // List<Event> events = new ArrayList<>();
    
    
        private void makeJsonObjectRequest() {
    
            RequestQueue requestQueue = Volley.newRequestQueue(getContext());
            String URL = Navigation_URL;
    
    
            StringRequest stringRequest = new StringRequest(Request.Method.GET, URL,
                    new Response.Listener<String>() {
                        @Override
                        public void onResponse(String response) {
                            try {
    
    
                                JSONArray jArray = new JSONArray(response);
                                for (int i = 0; i < jArray.length(); i++) {
                                    JSONObject jsonObject = jArray.getJSONObject(i);
                                    String StartDate = jsonObject.getString("StartDate");
                                    String Title = jsonObject.getString("Title");
    
    
                                    try {
                                        Date date = simpleDateFormat.parse(StartDate);
    
                                        Log.d("Date ", "" + date);
                                        CalendarDay day1 = CalendarDay.from(date);
                                        Event event = new Event(date, Title);
                                        cal = Calendar.getInstance();
                                        cal.setTime(date);
                                        int month = cal.get(Calendar.MONTH);
                                        if (!map.containsKey(month)) {
                                            List<Event> events = new ArrayList<>();
                                            events.add(event);
                                            map.put(month, events);
                                        } else {
                                            List<Event> events = map.get(month);
                                            events.add(event);
                                            map.put(month, events);
    
                                        }
                                        calevents.add(day1);
    
                                    } catch (ParseException e) {
                                        e.printStackTrace();
                                    }
    
    
                                }
    
                                //CalenderAdapter calenderAdapter = new CalenderAdapter(getActivity(), student_list_calender);
                                //listView.setAdapter(calenderAdapter);
                                cal = Calendar.getInstance();
                                int month = cal.get(Calendar.MONTH);
                                List<Event> event = map.get(month);
                                if (event != null && event.size() > 0)
                                    adapter.addItems(event);
                                listView.setAdapter(adapter);
                                EventDecorator eventDecorator = new EventDecorator(Color.RED, calevents);
                                calendarView.addDecorator(eventDecorator);
    
                            } catch (JSONException e) {
                                makeText(getContext(), "Fetch failed!", LENGTH_SHORT).show();
                                e.printStackTrace();
                            }
    
                            //
                        }
    
                    }, new Response.ErrorListener() {
                @Override
                public void onErrorResponse(VolleyError error) {
                    makeText(getContext(), error.toString(), LENGTH_LONG).show();
                }
            }) {
    
                @Override
                public Map<String, String> getHeaders() throws AuthFailureError {
                    Map<String, String> headers = new HashMap<String, String>();
                    headers.put("Authorization", "Bearer " + access_token);
                    headers.put("Content-Type", "application/x-www-form-urlencoded");
                    return headers;
                }
    /*
                @Override
                protected Map<String, String> getParams() throws com.android.volley.AuthFailureError {
                    Map<String, String> map = new HashMap<String, String>();
    
                    map.put("id", master_id);
                    map.put("accessID", accessID);
                    map.put("currentUser", master_id);
                    return map;
    
                } */
            };
    
    
            requestQueue.add(stringRequest);
    
        }
    
    
        @Override
        public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
            // TODO Auto-generated method stub
            super.onCreateOptionsMenu(menu, inflater);
            inflater.inflate(R.menu.dashboard, menu);
        }
    
    
        @Override
        public boolean onOptionsItemSelected(MenuItem item) {
            // handle item selection
            switch (item.getItemId()) {
                case R.id.action_settings:
                    // do s.th.
                    return true;
                default:
                    return super.onOptionsItemSelected(item);
            }
        }
    
    
        @Override
        public void onMonthChanged(MaterialCalendarView widget, CalendarDay date) {
    
    
            // CalenderAdapter calenderAdapter = new CalenderAdapter(getActivity(), student_list_calender);
            // listView.setAdapter(calenderAdapter);
            Calendar cal = Calendar.getInstance();
            cal.setTime(date.getDate());
            int month = cal.get(Calendar.MONTH);
            List<Event> event = map.get(month);
            if (event != null && event.size() > 0)
                adapter.addItems(event);
    
            widget.invalidateDecorators();
    
        }
    
    
    }
    

    EventDecorator

          public class EventDecorator implements DayViewDecorator {
    
    /*
        private final Drawable drawable;
        private final CalendarDay day;
        private final int color;
    
    
        public EventDecorator(MaterialCalendarView view, Date date, int colors) {
    //       super(view);
    
            this.day = CalendarDay.from(date);
            this.color = colors;
            this.drawable = createTintedDrawable(view.getContext(), color);
        }
    
    
        @Override
        public boolean shouldDecorate(CalendarDay day) {
            if (this.day.equals(day)) {
                return true;
            }
            return false;
        }
    
        @Override
        public void decorate(DayViewFacade view) {
            view.setSelectionDrawable(drawable);
        }
    
        private static Drawable createTintedDrawable(Context context, int color) {
            return applyTint(createBaseDrawable(context), color);
        }
    
        private static Drawable applyTint(Drawable drawable, int color) {
            Drawable wrappedDrawable = DrawableCompat.wrap(drawable);
            DrawableCompat.setTint(wrappedDrawable, color);
            return wrappedDrawable;
        }
    
        private static Drawable createBaseDrawable(Context context) {
            return ContextCompat.getDrawable(context, R.drawable.ic_menu_send);
        }
    
    
       */
    
        private int color;
        private HashSet<CalendarDay> dates;
    
        public EventDecorator(int color, Collection<CalendarDay> dates) {
            this.color = color;
            this.dates = new HashSet<>(dates);
        }
    
        @Override
        public boolean shouldDecorate(CalendarDay day) {
            return dates.contains(day);
        }
    
        @Override
        public void decorate(DayViewFacade view) {
            view.addSpan(new DotSpan(5, color));
        }
    }
    

    Event

      public class Event {
    
        private Date date;
        private String events;
    
        public Event(Date date, String events) {
            this.date = date;
            this.events = events;
    
        }
    
        public Date getDate() {
            return date;
        }
    
        public String getEvents() {
            return events;
        }
    }
    

    MyAdapterCalendar

    public class MyAdapterCalendar extends ArrayAdapter<Event> {
    
        private List<Event> list;
        private LayoutInflater mInflater;
    
        public MyAdapterCalendar(Context context, List<Event> list) {
            super(context, R.layout.activity_calendar_event, list);
            this.mInflater = LayoutInflater.from(context);
            this.list = list;
        }
    
        static class ViewHolder {
            TextView text;
    
        }
    
        public void addItems(List<Event> list) {
            this.list.clear();
            this.list.addAll(list);
            notifyDataSetChanged();
    
        }
    
    
        @Override
        public View getView(int position, View convertView, ViewGroup parent) {
            ViewHolder viewHolder;
    
            if (convertView == null) {
    
                convertView = mInflater.inflate(R.layout.activity_calendar_event, parent, false);
                viewHolder = new ViewHolder();
                viewHolder.text = (TextView) convertView.findViewById(R.id.label);
    
                convertView.setTag(viewHolder);
            } else {
                viewHolder = (ViewHolder) convertView.getTag();
            }
    
            viewHolder.text.setText(list.get(position).getEvents());
    
            return convertView;
        }
    }
    

    activity_calendar_event

    <

    RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="match_parent"
        android:layout_height="wrap_content">
    
        <TextView
            android:id="@+id/label"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:gravity="center"
            android:text="Hello World"
            android:textSize="20sp"></TextView>
    
    
    </RelativeLayout>
    

    JSON

    [
      {
        "EventID": 1011,
        "Title": "May Day",
        "Description": "Holiday for the International Labour Day",
        "StartDate": "2017-05-01T00:00:00",
        "StartTime": "00:00:00",
        "EndDate": "2017-05-02T00:00:00",
        "EndTime": "00:00:00",
        "IsFullDay": true,
        "IsHoliday": false,
        "DateTime": null
      },
      {
        "EventID": 1020,
        "Title": "d",
        "Description": "",
        "StartDate": "2017-04-27T00:00:00",
        "StartTime": "05:45:00",
        "EndDate": "2017-04-27T00:00:00",
        "EndTime": "05:45:00",
        "IsFullDay": false,
        "IsHoliday": false,
        "DateTime": null
      },
      {
        "EventID": 1019,
        "Title": "Mother's Day",
        "Description": "Mother's day",
        "StartDate": "2017-04-26T00:00:00",
        "StartTime": "10:00:00",
        "EndDate": "2017-04-26T00:00:00",
        "EndTime": "18:00:00",
        "IsFullDay": false,
        "IsHoliday": false,
        "DateTime": null
      }
    ]
    

    I want to display the dot under certain date,which shows as event.And specific month should list specific month event rather than all the event ,which is the one i am getting on Currently.

  • seon
    seon about 7 years
    I will work on it.any useful link will be helpful.i will upvote surely it it help
  • Victor
    Victor about 7 years
    Refer :github.com/prolificinteractive/material-calendarview/tree/… .. if u find this answer helpful ,upvote
  • seon
    seon almost 7 years
    Red Dots are Shown.Can you guide me to Show the message(event) when clicked on the event Date?
  • Raghunandan
    Raghunandan almost 7 years
    @seon edited. i used a hashmap to get events based on month. You can use a different strategy depending how performant your app is
  • Raghunandan
    Raghunandan almost 7 years
    @seon and a sample to try it out github.com/raghunandankavi2010/SamplesAndroid/tree/master/…. The customization part is left to you. Note: You need not use the same methodology in production.
  • seon
    seon almost 7 years
    You have done through the Asset .So i am bit confused.Its not working??
  • seon
    seon almost 7 years
  • seon
    seon almost 7 years
    Can you help me to Compare the parent year to the year coming from the JSON Data
  • EdmDroid
    EdmDroid almost 7 years
    What is parent year in this case?