본문으로 바로가기

[안드로이드]달력 만들기(calendar)

category Android 2017. 8. 7. 15:23

안녕하세요!! 오늘은 안드로이드에서 달력을 만들어 보겠습니다!!


안드로이드 달력은 수많은 예제가 있는데요 


이번 포스트에서는 Material Calendar 를 사용하여 달력을 만들어 보도록 하겠습니다! 

https://github.com/prolificinteractive/material-calendarview

Material Calendar 의 GitHub 주소입니다. 


사용하기에 앞서서 Build에 compile 'com.prolificinteractive:material-calendarview:1.4.3' 라이브러리를 추가 하도록 합니다.


Material Calendar 에서는 다양한 형태의 Calendar를 제공 합니다. 


우선 가장 기본적인 Calendar사용법을 알아보겠습니다.


xml에서는 

<com.prolificinteractive.materialcalendarview.MaterialCalendarView
        xmlns:app="http://schemas.android.com/apk/res-auto"
        android:id="@+id/calendarView"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        app:mcv_selectionColor="#a9dbf0cb"
        app:mcv_showOtherDates="defaults" />


추가해줍니다.

// showOtherDates 에는 여러 옵션이 있습니다 

// 기본적으로 defaults 값은 현재 달(month)만 보여줍니다.

// 이전달의 날자와 다음달 날자의일부를 보여주는 옵션도 가능합니다.



java코드로 넘어와서 


@Bind(R.id.calendarView)
    MaterialCalendarView materialCalendarView;

MaterialCalendarView 를 바인드 해줍니다. (findViewById 로 얻어와도 됩니다)


MaterialCalendarView에는


materialCalendarView.state().edit()
                .setFirstDayOfWeek(Calendar.SUNDAY)
                .setMinimumDate(CalendarDay.from(2017, 0, 1))
                .setMaximumDate(CalendarDay.from(2030, 11, 31))
                .setCalendarDisplayMode(CalendarMode.MONTHS)
                .commit();View);

달력의 시작과 끝을 지정해줄수 있습니다.

 materialCalendarView.addDecorators(
                new SundayDecorator(),
                new SaturdayDecorator(),
                oneDayDecorator);

addDecorators 로 달력에 효과를 줄수있습니다.

예를들어



처럼 SundayDecorator()와 SaturdayDecorator()로 토요일,일요일에 색을 줄수 있고 onDayDecorator()로 오늘 날자에 지정색을 줄 수 있습니다.


SundayDecorator(),SaturdayDecorator(),onDayDecorator() 의 예시는 포스트 아래에 올려두겠습니다!


그 외에도 클릭이벤트(아래)

materialCalendarView.setOnDateChangedListener(new OnDateSelectedListener() {
            @Override
            public void onDateSelected(@NonNull MaterialCalendarView widget, @NonNull CalendarDay date, boolean selected) {
  }
} 

특정 날자에 효과표시 기능이 있습니다. (아래)

    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;
            }
 
            materialCalendarView.addDecorator(new EventDecorator(Color.RED, calendarDays));        }
    }

위 예제는 

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

현재 달(month)의 2달전부터 5일 간격으로 30개의 (i<30) 
widget.addDecorator(new EventDecorator(Color.RED, calendarDays));

빨간점을 찍는 이벤트로 되어있습니다.

이부분을 사용자에 맞게 변형시키면 원하는 날자에 특별한 효과를 줄 수 있습니다.

이상으로 아~주 기본적인 material calendar 에 대해 알아보았습니다.
 
자세한 내용은 GitHub를 참고해주세요.

SundayDecorator.JAVA
public class SundayDecorator implements DayViewDecorator {
 
    private final Calendar calendar = Calendar.getInstance();
 
    public SundayDecorator() {
    }
 
    @Override
    public boolean shouldDecorate(CalendarDay day) {
        day.copyTo(calendar);
        int weekDay = calendar.get(Calendar.DAY_OF_WEEK);
        return weekDay == Calendar.SUNDAY;
    }
 
    @Override
    public void decorate(DayViewFacade view) {
        view.addSpan(new ForegroundColorSpan(Color.RED));
    }
}

SaturdayDecorator.JAVA

public class SaturdayDecorator implements DayViewDecorator {
 
    private final Calendar calendar = Calendar.getInstance();
 
    public SaturdayDecorator() {
    }
 
    @Override
    public boolean shouldDecorate(CalendarDay day) {
        day.copyTo(calendar);
        int weekDay = calendar.get(Calendar.DAY_OF_WEEK);
        return weekDay == Calendar.SATURDAY;
    }
 
    @Override
    public void decorate(DayViewFacade view) {
        view.addSpan(new ForegroundColorSpan(Color.BLUE));
    }
}

onDatDecorator.JAVA

public class OneDayDecorator implements DayViewDecorator {
 
    private CalendarDay date;
 
    public OneDayDecorator() {
        date = CalendarDay.today();
    }
 
    @Override
    public boolean shouldDecorate(CalendarDay day) {
        return date != null && day.equals(date);
    }
 
    @Override
    public void decorate(DayViewFacade view) {
        view.addSpan(new StyleSpan(Typeface.BOLD));
        view.addSpan(new RelativeSizeSpan(1.4f));
        view.addSpan(new ForegroundColorSpan(Color.GREEN));
    }
 
    /**
     * We're changing the internals, so make sure to call {@linkplain MaterialCalendarView#invalidateDecorators()}
     */
    public void setDate(Date date) {
        this.date = CalendarDay.from(date);
    }
}

EventDecorator.java

package com.project.sample_calendar.decorators;

import android.app.Activity;
import android.graphics.drawable.Drawable;

import com.project.sample_calendar.R;
import com.prolificinteractive.materialcalendarview.CalendarDay;
import com.prolificinteractive.materialcalendarview.DayViewDecorator;
import com.prolificinteractive.materialcalendarview.DayViewFacade;

import java.util.Collection;
import java.util.HashSet;

/**
 * Decorate several days with a dot
 */
public class EventDecorator implements DayViewDecorator {

    private final Drawable drawable;
    private int color;
    private HashSet<CalendarDay> dates;

    public EventDecorator(int color, Collection<CalendarDay> dates,Activity context) {
        drawable = context.getResources().getDrawable(R.drawable.more);
        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.setSelectionDrawable(drawable);
        //view.addSpan(new DotSpan(5, color)); // 날자밑에 점
    }
}

달력예제는 포스트 처음 github 로 가시면 다운받을수 있습니다!!

혹시 제가 사용한 달력 예제를 원하시면 댓글로 남겨주세요.



-----------------------------------------------------------------------------------------------------------------

예제를 원하시는분이 많아 git에 올려두었습니다.

https://github.com/dolsanta/Sample_Calendar