728x90

달력 데이터를 생성하는 것은 ArrayList 또는 Hashmap 을 이용한다.


먼저 달력 데이터 Class 를 구현한다.

package com.link2me.android.item;

public class Calendar_Item {
    private  String year; // 년
    private  String month; // 월
    private  String day; // 일
    private  int weekday; // 요일
    private  String color; // 색상
    private String event;
    private String key; // 월일 값을 key 로 사용

    public Calendar_Item() {
    }

    public Calendar_Item(String year, String month, String day, int weekday, String color) {
        this.year = year;
        this.month = month;
        this.day = day;
        this.weekday = weekday;
        this.color = color;
    }

    public String getYear() {
        return year;
    }

    public void setYear(String year) {
        this.year = year;
    }

    public String getMonth() {
        return month;
    }

    public void setMonth(String month) {
        this.month = month;
    }

    public String getDay() {
        return day;
    }

    public void setDay(String day) {
        this.day = day;
    }

    public int getWeekday() {
        return weekday;
    }

    public void setWeekday(int weekday) {
        this.weekday = weekday;
    }

    public String getColor() {
        return color;
    }

    public void setColor(String color) {
        this.color = color;
    }

    public String getEvent() {
        return event;
    }

    public void setEvent(String event) {
        this.event = event;
    }

    public String getKey() {
        return key;
    }

    public void setKey(String key) {
        this.key = key;
    }
}


먼저 작성했던 MainActivity 에서 makeCalendarList(int CurrentMonth, int yy) 메소드를 추가하면서 필요한 코드를 작성한다.

여기서는 공휴일 데이터를 추가하는 루틴을 생략했다.

공휴일 데이터 추가 샘플은 https://link2me.tistory.com/1699 게시글과 다음 게시글인 CalendarHelper 를 같이 참조하며 CalendarHelper 에 필요한 사항을 추가하고 수정해서 구현하도록 개발자의 몫으로 남겼다.


class package com.link2me.android.calendar;

import android.content.Context;
import android.content.DialogInterface;
import android.os.Bundle;
import android.text.format.DateFormat;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.EditText;
import android.widget.GridView;
import android.widget.ImageView;
import android.widget.TextView;

import androidx.appcompat.app.AlertDialog;
import androidx.appcompat.app.AppCompatActivity;

import com.link2me.android.adpater.GridCellAdapter;
import com.link2me.android.item.Calendar_Item;
import com.link2me.android.item.Holidays_Item;
import com.link2me.android.util.CalendarHelper;

import java.text.ParseException;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.HashMap;
import java.util.Locale;

public class MainActivity extends AppCompatActivity implements View.OnClickListener {
    private static final String TAG = MainActivity.class.getSimpleName();
    private Context mContext;

    private TextView currentMonth;
    private ImageView prevYear;
    private ImageView prevMonth;
    private ImageView nextMonth;
    private ImageView nextYear;
    private ImageView selectDate;

    private GridView calendarView;
    private GridCellAdapter adapter;
    private Calendar cal;
    private int month, year;
    private static final String dateTemplate = "yyyy MMMM";

    private ArrayList<Calendar_Item> calList = new ArrayList<>();
    private static final int DAY_OFFSET = 1;
    private final String[] weekdays = new String[] { "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" };
    private int lastDays;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        mContext = MainActivity.this;

        cal = Calendar.getInstance(Locale.getDefault());
        month = cal.get(Calendar.MONTH) + 1;
        year = cal.get(Calendar.YEAR);

        prevYear = (ImageView) this.findViewById(R.id.prevYear);
        prevYear.setOnClickListener(this);

        prevMonth = (ImageView) this.findViewById(R.id.prevMonth);
        prevMonth.setOnClickListener(this);

        currentMonth = (TextView) this.findViewById(R.id.currentMonth);
        currentMonth.setText(year +"년 " + month + "월");
        currentMonth.setOnClickListener(this);

        nextMonth = (ImageView) this.findViewById(R.id.nextMonth);
        nextMonth.setOnClickListener(this);

        nextYear = (ImageView) this.findViewById(R.id.nextYear);
        nextYear.setOnClickListener(this);

        selectDate = (ImageView) this.findViewById(R.id.selectDate);
        selectDate.setOnClickListener(this);

        calendarView = (GridView) this.findViewById(R.id.calendar);

        makeCalendarList(month, year);

        // Initialised
        adapter = new GridCellAdapter(mContext, calList);
        adapter.notifyDataSetChanged();
        calendarView.setAdapter(adapter);
    }

    private void setGridCellAdapterToDate(int month, int year) {
        makeCalendarList(month, year);
        adapter = new GridCellAdapter(mContext, calList);
        adapter.notifyDataSetChanged();
        calendarView.setAdapter(adapter);
        // 상단 화면 날짜 출력
        currentMonth.setText(year +"년 " + month + "월");
    }

    private void makeCalendarList(int CurrentMonth, int yy) {
        int trailingSpaces = 0;
        int daysInPrevMonth = 0;
        int prevMonth = 0;
        int prevYear = 0;
        int nextMonth = 0;
        int nextYear = 0;

        calList.clear();

        Calendar cal = Calendar.getInstance();

        int thisYear = cal.get(Calendar.YEAR);

        int thisMonth = cal.get(Calendar.MONTH); // 현재 월
        int thisDay = cal.get(Calendar.DAY_OF_MONTH); // 오늘 날짜
        cal.set(yy,CurrentMonth-1,1); // 0 ~ 11월로 인식하므로 - 1, 입력된 년월
        Log.e(TAG, "Calendar SET := " + cal.getTime().toString());
        lastDays = cal.getActualMaximum(Calendar.DAY_OF_MONTH);

        if (CurrentMonth == 12) {
            prevMonth = CurrentMonth - 1;
            nextMonth = 1;
            prevYear = yy;
            nextYear = yy + 1;
            daysInPrevMonth = CalendarHelper.getLastDay(prevMonth,prevYear);
        } else if (CurrentMonth == 1) {
            prevMonth = 12;
            prevYear = yy - 1;
            nextYear = yy;
            nextMonth = CurrentMonth + 1;
            daysInPrevMonth = CalendarHelper.getLastDay(prevMonth,prevYear);
        } else {
            prevMonth = CurrentMonth - 1;
            nextMonth = CurrentMonth + 1;
            nextYear = yy;
            prevYear = yy;
            daysInPrevMonth = CalendarHelper.getLastDay(prevMonth,prevYear);
        }

        int currentWeekDay = cal.get(Calendar.DAY_OF_WEEK) - 1;
        trailingSpaces = currentWeekDay;

        // 이전월 데이터 채우기 위한 리스트 추가
        for (int i = 0; i < trailingSpaces; i++) {
            String key = String.format("%02d",prevMonth)+String.format("%02d",(daysInPrevMonth - trailingSpaces + DAY_OFFSET) + i);
            addCalendarItem(String.valueOf(prevYear),String.valueOf(prevMonth),String.valueOf((daysInPrevMonth - trailingSpaces + DAY_OFFSET) + i),
                    0,"GRAY","",key);
        }

        // 현재월 데이터 리스트 추가
        for (int i = 1; i <= lastDays; i++) {
            String date = String.valueOf(yy)+String.format("%02d",CurrentMonth)+String.format("%02d",i);
            String key = String.format("%02d",CurrentMonth)+String.format("%02d",i);
            try {
                int weekday = CalendarHelper.WeekendValue(date);
                if(weekday == 1) // 일요일
                    addCalendarItem(String.valueOf(yy),String.valueOf(CurrentMonth),String.valueOf(i),weekday,"RED","",key);
                else if(weekday == 7) // 토요일
                    addCalendarItem(String.valueOf(yy),String.valueOf(CurrentMonth),String.valueOf(i),weekday,"BLUE","",key);
                else
                    addCalendarItem(String.valueOf(yy),String.valueOf(CurrentMonth),String.valueOf(i),weekday,"BLACK","",key);
                if(CurrentMonth-1 == thisMonth){ // 현재월이면
                    if(i == thisDay){
                        Log.e(TAG, "key := " + key);
                        int index = getIndexOfCalList(key);
                        Calendar_Item item = calendarItem(String.valueOf(yy),String.valueOf(CurrentMonth),String.valueOf(i),weekday,"CYAN","",key);
                        calList.set(index,item);
                    }
                }
            } catch (ParseException e) {
                e.printStackTrace();
            }
        }

        // 다음달 데이터 채우기 리스트 추가
        for (int i = 0; i < calList.size() % 7; i++) {
            String key = String.format("%02d",nextMonth)+String.format("%02d",i+1);
            addCalendarItem(String.valueOf(nextYear),String.valueOf(nextMonth),String.valueOf(i+1),0,"GRAY",
                    "",key);
        }

    }

    private Calendar_Item calendarItem(String year, String month, String day, int weekday, String color, String name, String key){
        Calendar_Item item = new Calendar_Item();
        item.setYear(year);
        item.setMonth(month);
        item.setDay(day);
        item.setWeekday(weekday);
        item.setColor(color);
        item.setEvent(name);
        item.setKey(key);
        return item;
    }

    private void addCalendarItem(String year, String month, String day, int weekday, String color,String name, String key){
        Calendar_Item item = calendarItem(year,month,day,weekday,color,name,key);
        calList.add(item);
    }

    private int getIndexOfCalList(String search_key) {
        for (int temp = 0; temp < calList.size(); temp++) {
            String key = calList.get(temp).getKey();
            if (key != null && key.equals(search_key)) {
                return temp;
            }
        }
        return -1;
    }

    private String getWeekDayAsString(int i) {
        return weekdays[i];
    }
}


참고 도움될 자료 : https://www.toptal.com/android/android-customization-how-to-build-a-ui-component-that-does-what-you-want


다음은 CalendarHelper Class 를 만들어서 음력/양력 변환, 공휴일 처리, 한달의 마지막 날짜 구하기 등 메소드를 구현한다.

블로그 이미지

Link2Me

,