정상에서 IT를 외치다

[Android, Custom Calendar] Custom Calendar 만들기 본문

안드로이드

[Android, Custom Calendar] Custom Calendar 만들기

Black-Jin 2018. 3. 28. 14:57
반응형


이번에는 달력을 커스텀 해서 만들어 보겠습니다.


아래 링크에서 가져온 예제를 커스텀 해봤습니다.


https://www.toptal.com/android/android-customization-how-to-build-a-ui-component-that-does-what-you-want


Calendar 관련 함수를 모르시는 분은 


http://black-jin0427.tistory.com/18 링크를 보고 와주세요




색깔도 오렌지 하게 ~ 오늘 날짜의 레이아웃도 오렌지 하게 바꾸어 보았습니다.


중요 소스만 설명하겠습니다.


public void updateCalendar(HashSet<Date> events)
{
ArrayList<Date> cells = new ArrayList<>();
Calendar calendar = (Calendar)currentDate.clone();

// determine the cell for current month's beginning
calendar.set(Calendar.DAY_OF_MONTH, 1);
int monthBeginningCell = calendar.get(Calendar.DAY_OF_WEEK) - 1;

// move calendar backwards to the beginning of the week
calendar.add(Calendar.DAY_OF_MONTH, -monthBeginningCell);

// fill cells
while (cells.size() < DAYS_COUNT)
{
cells.add(calendar.getTime());
calendar.add(Calendar.DAY_OF_MONTH, 1);
}

// update grid
grid.setAdapter(new CalendarAdapter(getContext(), cells, events));

// update title
SimpleDateFormat sdf = new SimpleDateFormat(dateFormat);
txtDate.setText(sdf.format(currentDate.getTime()));

// set header color according to current season
int month = currentDate.get(Calendar.MONTH);
int season = monthSeason[month];
int color = rainbow[season];

header.setBackgroundColor(getResources().getColor(color));
}

달력을 업데이트 하는 함수 입니다.


2018년 3월 28일 수요일을 기준으로 설명하겠습니다.


calendar.get(Calendar.DAY_OF_MONTH) 의 값은 28  -> 오늘 날짜 28일을 가리킴

calendar.get(Calendar.DAY_OF_WEEK) 의 값은 4 -> 오늘의 요일인 수요일을 가리킴 (1 : 일요일, ~ 7 : 토요일)

calendar.set(Calendar.DAY_OF_MONTH, 1);

을 하여 오늘 날짜를 1일로 변경합니다.


그럼

calendar.get(Calendar.DAY_OF_MONTH) 의 값은 1  -> set 함수를 사용하여 1일로 변경

calendar.get(Calendar.DAY_OF_WEEK) 의 값은 5  -> 상단 이미지 오렌지 달력에서 1일은 목요일 입니다. 


int monthBeginningCell = calendar.get(Calendar.DAY_OF_WEEK) - 1;

는 5 - 1 = 4 가 됩니다.


3월 1일의 요일인 목요일을 구하고 달력의 첫 째 주에서 4번째 칸부터 1 일 시작임을 보여줍니다. (일요일이 0 번째 칸입니다.)

calendar.add(Calendar.DAY_OF_MONTH, -monthBeginningCell);


calendar.get(Calendar.DAY_OF_MONTH) 의 값은 1 이였는데 여기에 - 4 를 해줍니다.


그럼 3월 1일 에서 -4일이 되어 2월 25일 입니다.


그럼 이제 calendar 의 getTime 을 해보면 Sun Feb 25 14:44:15 GMT+09:00 2018


요렇게 2월 25일 과 현재 시간으로 바뀌게 됩니다.


즉 위 작업을 통해 오늘 날짜로 되어 있던  Calendar 객체를 2월 25일의 객체로 변경하였습니다.


while (cells.size() < DAYS_COUNT)
{
cells.add(calendar.getTime());
calendar.add(Calendar.DAY_OF_MONTH, 1);
}

DAYS_COUNT = 48 (7일 * 6주) 입니다. 위 오렌지 달력의 칸이 모두 48개 이죠? 이걸 나타냅니다.


ArrayList<Date> cells = new ArrayList<>();

cells 애 48칸에 들어갈 하나 하나의 Date 값을 넣어 줄껍니다. (Date 는  java.util 에 있는 기본 객체 입니다.)


calendar 의 getItem() 을 하면 calendar 의  Date 값을 가져올 수 있습니다.


2월 25일의 Date 값 Sun Feb 25 14:44:15 GMT+09:00 2018 을 추가해 주고


calendar.add(Calendar.DAY_OF_MONTH, 1) 을 하여 2월 26일 로 만들고 그 값의  Date 를 calls 배열에 넣어 줍니다.


이렇게 2월 25일 ~ 28일 , 3월 1일 ~ 31일 , 4월 1일 ~ 7일 까지 


48개의 데이터를 cells 의 넣어주면 while 구문을 벗어납니다.


grid.setAdapter(new CalendarAdapter(getContext(), cells, events));

cells 데이터를 어댑터네 넣어주면 좌르르륵 뷰가 생성됩니다.


(달력은 grid 뷰로 구성되어 있습니다. 상단 링크 예제 확인)


저는 어댑터 부분을 약간 수정하였습니다.

private class CalendarAdapter extends ArrayAdapter<Date>
{
// days with events
private HashSet<Date> eventDays;

// for view inflation
private LayoutInflater inflater;

public CalendarAdapter(Context context, ArrayList<Date> days, HashSet<Date> eventDays)
{
super(context, R.layout.item_view_calendar, days);
this.eventDays = eventDays;
inflater = LayoutInflater.from(context);
}

@Override
public View getView(int position, View view, ViewGroup parent)
{
// day in question
Date date = getItem(position);
int day = date.getDate();
int month = date.getMonth();
int year = date.getYear();

// today
Date today = new Date();

// inflate item if it does not exist yet
if (view == null)
view = inflater.inflate(R.layout.item_view_calendar, parent, false);

RelativeLayout rlItemViewCalendar = view.findViewById(R.id.rlItemViewCalendar);
TextView tvItemViewCalendar = view.findViewById(R.id.tvItemViewCalendar);

// if this day has an event, specify event image
if (eventDays != null)
{
for (Date eventDate : eventDays)
{
if (eventDate.getDate() == day &&
eventDate.getMonth() == month &&
eventDate.getYear() == year)
{
// mark this day for event
break;
}
}
}

// clear styling
tvItemViewCalendar.setTypeface(null, Typeface.NORMAL);
tvItemViewCalendar.setTextColor(Color.BLACK);

if (month != today.getMonth() || year != today.getYear())
{
// if this day is outside current month, grey it out
tvItemViewCalendar.setTextColor(getResources().getColor(R.color.greyed_out));
}
else if (day == today.getDate())
{
// if it is today, set it to blue/bold
tvItemViewCalendar.setTypeface(null, Typeface.BOLD);
tvItemViewCalendar.setTextColor(getResources().getColor(R.color.today));

rlItemViewCalendar.setBackgroundColor(getResources().getColor(R.color.darkOrange));
}

// set text
tvItemViewCalendar.setText(String.valueOf(date.getDate()));

return view;
}
}

위와 같고 item_view_calendar 은

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
android:id="@+id/rlItemViewCalendar"
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="50dp">

<TextView
android:id="@+id/tvItemViewCalendar"
android:textSize="10dp"
android:layout_centerInParent="true"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center"
android:text="00" />

</RelativeLayout>

와 같이 하여 텍스트와 배경 색을 변경할 수 있게 했습니다.


이렇게 달력 커스텀마이징 완성~~!!

반응형
Comments