728x90

Calendar Class 를 사용하여 달력을 만드는데 알아둘 사항을 정리했다.

Date는 JDK1.0, Calendar는 JDK1.1 부터 제공되었다.

Calendar는 추상클래스라서 객체를 직접 생성할 수 없고, 메소드를 통해서 완전히 구현된 클래스의 인스턴스를 얻어야 한다.

Calendar cal = new Calendar(); // 에러. 추상클래스는 인스턴스를 생성할 수 없다.

Calendar cal = Calendar.getInstance(); // getInstance()는 Calendar 클래스의 인스턴스를 반환


아래 코드는 Java에서 작성한 코드다.

package Calendar;

import java.util.Calendar;

public class Calendar_EX {

    public static void main(String[] args) {
        // Calendar Class 를 사용한 달력 구현을 위한 기본사항 알아보기
        int year = 2019;
        int month = 2;
        int trailingSpaces = 0;
        int daysInPrevMonth = 0;
        int prevYear = 0;
        int prevMonth = 0;
        int DAY_OFFSET = 1;
       
        Calendar cal = Calendar.getInstance(); //Calendar 객체 생성(시스템의 현재 날짜와 시간 정보)
        System.out.println("today is "+cal.getTime()); // 현재시각을 알려주는 메소드
        System.out.println("올해 년도 : " + cal.get(Calendar.YEAR));
        System.out.println("이번 달(0~11, 0:1월): " + cal.get(Calendar.MONTH));
        System.out.println("이번 달의 오늘 날짜 : " + cal.get(Calendar.DATE));
       
        int LastDays = cal.getActualMaximum(Calendar.DATE); //해당 월 마지막 날짜
        System.out.println("이번달의 마지막날짜 : "+LastDays); // 현재시각을 알려주는 메소드
        int dayofweek = cal.get(Calendar.DAY_OF_WEEK); // 현재 요일 (일요일은 1, 토요일은 7)
        System.out.println("이번달 오늘날짜 요일 값 : "+dayofweek); // 오늘날짜의 요일값을 반환
       
        System.out.println("이번년도의 몇째 주 : "+ cal.get(Calendar.WEEK_OF_YEAR));
        System.out.println("이번달의 몇째 주 : "+ cal.get(Calendar.WEEK_OF_MONTH));
        System.out.println("이번달의 몇째 주 : " + cal.get(Calendar.DAY_OF_WEEK_IN_MONTH));
        System.out.println("현재 시간 : "+ cal.get(Calendar.HOUR)); // 현재 시간 (12시간제)
        System.out.println("현재 시간 : "+ cal.get(Calendar.HOUR_OF_DAY)); // 현재 시간 (24시간제)
        System.out.println("오전_오후(0:오전, 1:오후): " + cal.get(Calendar.AM_PM));
        System.out.println("현재 분 : "+ cal.get(Calendar.MINUTE));
        System.out.println("현재 초 : "+ cal.get(Calendar.SECOND));
        String time = String.valueOf(cal.get(Calendar.HOUR)) + "시 " +
                String.valueOf(cal.get(Calendar.MINUTE)) + "분 " +
                String.valueOf(cal.get(Calendar.SECOND)) + "초" ;
        System.out.println("현재 시간 : "+ time);
       
       
        //set메소드를 통해 연도 월 일 을 설정
        cal.set(Calendar.YEAR, Integer.valueOf(year));
        cal.set(Calendar.MONTH, Integer.valueOf(month)-1); // 0 ~ 11월이라  1을 빼줌
        cal.set(Calendar.DAY_OF_MONTH, 1); // 지정 월의 날짜
        // 년 월 일을 나누어서 표현했고, 아래는 하나로 년월일을 지정
        //cal.set(year,month-1,1); // 0 ~ 11월로 인식하므로 - 1, 입력된 년월

        LastDays = cal.getActualMaximum(Calendar.DATE); //지정한 월의 마지막 날짜
        System.out.println("SET 지정달 마지막날짜 : "+LastDays);

        dayofweek = cal.get(Calendar.DAY_OF_WEEK); // 지정날짜 요일 (일요일은 1, 토요일은 7)
        System.out.println("SET 지정달 week 값 : "+dayofweek); // 지정날짜의 1일의 요일 값을 표시
        trailingSpaces = dayofweek -1;
        prevMonth = month -1;
        prevYear = year;
        daysInPrevMonth = getLastDay(prevMonth,prevYear);
        System.out.println("SET 이전달 마지막날짜 : "+daysInPrevMonth);
        // 이번달 1일 이전 공백 부분을 채우기 위한 이전달 날짜
        for (int i = 0; i < trailingSpaces; i++) {
             System.out.println("SET 이전달 날짜 : "+ String.valueOf((daysInPrevMonth - trailingSpaces + DAY_OFFSET) + i));
        }
    }

    // 달의 마지막 일을 구함
    private static int getLastDay(int month, int year) {
        if (month == 4 || month == 6 || month == 9 || month == 11) {
            return 30;
        } else if (month == 2 && isLeapYear(year) == true) {
            return 29;
        } else if (month == 2 && isLeapYear(year) == false) {
            return 28;
        } else {
            return 31;
        }
    }

    // 해당 년도가 윤년인지 판별
    private static boolean isLeapYear(int year) {
        return (((year % 4 == 0) && (year % 100 != 0)) || (year % 400 == 0));
    }
}


블로그 이미지

Link2Me

,
728x90

안드로이드 달력 화면에 뿌려줄 GridCellAdapter 코드는 아래와 같다.


package com.link2me.android.adpater;

import android.content.Context;
import android.graphics.Color;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.LinearLayout;
import android.widget.TextView;

import com.link2me.android.calendar.R;
import com.link2me.android.item.Calendar_Item;
import com.link2me.android.util.CalendarHelper;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;

public class GridCellAdapter extends BaseAdapter implements View.OnClickListener {
    private static final String tag = GridCellAdapter.class.getSimpleName();
    private final Context mContext;

    private final ArrayList<Calendar_Item> calList;
    private LinearLayout gridcell_layout;
    private TextView gridcell_Day;
    private TextView gridcell_LunarDay;
    private TextView gridcell_Event;
    private final SimpleDateFormat dateFormatter = new SimpleDateFormat("dd-MMM-yyyy");

    public GridCellAdapter(Context context, ArrayList<Calendar_Item> list) {
        mContext = context;
        calList = list;
    }

    public Calendar_Item getItem(int position) {
        return calList.get(position);
    }

    @Override
    public int getCount() {
        return calList.size();
    }

    @Override
    public long getItemId(int position) {
        return position;
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        View view = convertView;
        if (view == null) {
            LayoutInflater inflater = (LayoutInflater) mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
            view = inflater.inflate(R.layout.calendar_cell, parent, false);
        }

        // Get a reference to the Day gridcell_layout
        gridcell_layout = (LinearLayout) view.findViewById(R.id.calendar_day_gridcell);
        gridcell_Day = view.findViewById(R.id.dayTV);
        gridcell_LunarDay = view.findViewById(R.id.lunardayTV);
        gridcell_Event = view.findViewById(R.id.eventTV);
        gridcell_layout.setOnClickListener(this);

        String theday = calList.get(position).getDay();
        int themonth = Integer.parseInt(calList.get(position).getMonth());
        String theyear = calList.get(position).getYear();
        String holiday = calList.get(position).getEvent();

        // Set the Day GridCell
        gridcell_Day.setText(theday);
        gridcell_LunarDay.setText(CalendarHelper.Sol2Lun(theyear, String.valueOf(themonth-1),theday)); //0 ~ 11월로 인식하므로 - 1
        if(holiday.length()>0){
            gridcell_Event.setText(holiday);
        } else {
            gridcell_Event.setText("");
        }
        gridcell_layout.setTag(theday + "-" + themonth + "-" + theyear);

        if(calList.get(position).getColor().equals("GRAY")){
            gridcell_Day.setTextColor(Color.LTGRAY);
        }
        if(calList.get(position).getColor().equals("BLACK")){
            gridcell_Day.setTextColor(Color.BLACK);
        }
        if(calList.get(position).getColor().equals("RED")){
            gridcell_Day.setTextColor(Color.RED);
            gridcell_Event.setTextColor(Color.RED);
        }
        if(calList.get(position).getColor().equals("BLUE")){
            gridcell_Day.setTextColor(Color.BLUE);
        }
        if(calList.get(position).getColor().equals("CYAN")){
            gridcell_layout.setBackgroundColor(Color.CYAN);
        }
        return view;
    }

    @Override
    public void onClick(View view) {
        String date_month_year = (String) view.getTag();
        Log.e("Selected date", date_month_year);
        try {
            Date parsedDate = dateFormatter.parse(date_month_year);
            Log.d(tag, "Parsed Date: " + parsedDate.toString());

        } catch (ParseException e) {
            e.printStackTrace();
        }
    }

}


calendar_cell.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/calendar_day_gridcell"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:background="@drawable/day_cell_bg"
    android:orientation="vertical"
    android:padding="7dp">

    <TextView
        android:id="@+id/dayTV"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="8"
        android:textStyle="bold"
        android:textSize="24sp" />

    <TextView
        android:id="@+id/lunardayTV"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="right"
        android:text="00.16"
        android:textSize="10sp" />

    <TextView
        android:id="@+id/eventTV"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:ellipsize="end"
        android:maxLines="1"
        android:text="기념일"
        android:textColor="#ff0000" />

</LinearLayout>



블로그 이미지

Link2Me

,
728x90

CalendarHelper Class 를 생성하여 양력/음력 변환, 음력/양력 변환, 한달의 마지막날짜 구하기 등을 하는 메소드를 구현한다.


package com.link2me.android.util;

import com.ibm.icu.util.ChineseCalendar;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;

public class CalendarHelper {
    /**
     * 음력날짜를 양력날짜로 변환
     * @param 음력날짜 (yyyyMMdd)
     * @return 양력날짜 (yyyyMMdd)
     */
    public static String Lunar2Solar(String yyyymmdd) {
        ChineseCalendar cc = new ChineseCalendar();
        Calendar cal = Calendar.getInstance();

        if (yyyymmdd == null)
            return "";

        String date = yyyymmdd.trim();
        if (date.length() != 8) {
            if (date.length() == 4)
                date = date + "0101";
            else if (date.length() == 6)
                date = date + "01";
            else if (date.length() > 8)
                date = date.substring(0, 8);
            else
                return "";
        }

        cc.set(ChineseCalendar.EXTENDED_YEAR, Integer.parseInt(date.substring(0, 4)) + 2637);
        cc.set(ChineseCalendar.MONTH, Integer.parseInt(date.substring(4, 6)) - 1);
        cc.set(ChineseCalendar.DAY_OF_MONTH, Integer.parseInt(date.substring(6)));

        cal.setTimeInMillis(cc.getTimeInMillis());

        int y = cal.get(Calendar.YEAR);
        int m = cal.get(Calendar.MONTH) + 1;
        int d = cal.get(Calendar.DAY_OF_MONTH);

        StringBuffer ret = new StringBuffer();
        ret.append(String.format("%04d", y));
        ret.append(String.format("%02d", m));
        ret.append(String.format("%02d", d));

        return ret.toString();
    }

    /**
     * 양력날짜를 음력날짜로 변환
     * @param 양력날짜 (yyyyMMdd)
     * @return 음력날짜 (yyyyMMdd)
     */
    public static String Solar2Lunar(String yyyymmdd) {
        ChineseCalendar cc = new ChineseCalendar();
        Calendar cal = Calendar.getInstance();

        if (yyyymmdd == null)
            return "";

        String date = yyyymmdd.trim() ;
        if( date.length() != 8 ) {
            if( date.length() == 4 )
                date = date + "0101" ;
            else if( date.length() == 6 )
                date = date + "01" ;
            else if( date.length() > 8 )
                date = date.substring(0,8) ;
            else
                return "" ;
        }

        cal.set( Calendar.YEAR, Integer.parseInt(date.substring(0,4)) ) ;
        cal.set( Calendar.MONTH, Integer.parseInt(date.substring(4,6))-1 ) ;
        cal.set( Calendar.DAY_OF_MONTH, Integer.parseInt(date.substring(6)) ) ;

        cc.setTimeInMillis( cal.getTimeInMillis() ) ;

        // ChinessCalendar.YEAR 는 1~60 까지의 값만 가지고 ,
        // ChinessCalendar.EXTENDED_YEAR 는 Calendar.YEAR 값과 2637 만큼의 차이를 가진다.
        int y = cc.get(ChineseCalendar.EXTENDED_YEAR)-2637 ;
        int m = cc.get(ChineseCalendar.MONTH)+1 ;
        int d = cc.get(ChineseCalendar.DAY_OF_MONTH) ;

        StringBuffer ret = new StringBuffer() ;
        if( y < 1000 )          ret.append( "0" ) ;
        else if( y < 100 )      ret.append( "00" ) ;
        else if( y < 10 )       ret.append( "000" ) ;
        ret.append( y ) ;

        if( m < 10 ) ret.append( "0" ) ;
        ret.append( m ) ;

        if( d < 10 ) ret.append( "0" ) ;
        ret.append( d ) ;

        return ret.toString() ;
    }

    public static int WeekendValue(String date) throws ParseException {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");
        Calendar cal = Calendar.getInstance();
        cal.setTime(sdf.parse(date));
        return cal.get(Calendar.DAY_OF_WEEK);
        // Calendar.SUNDAY : 1
        // Calendar.SATURDAY : 7
    }

    /**
     * 양력날짜의 요일을 리턴
     * @param 양력날짜 (yyyyMMdd)
     * @return 요일(int)
     */
    public static int getDayOfWeek(String day) {
        int y = Integer.parseInt(day.substring(0, 4));
        int m = Integer.parseInt(day.substring(4, 6)) - 1;
        int d = Integer.parseInt(day.substring(6));
        Calendar c = Calendar.getInstance();
        c.set(y, m, d);
        return c.get(Calendar.DAY_OF_WEEK);
    }

    public static String Sol2Lun(String year, String month, String day) {
        ChineseCalendar cc = new ChineseCalendar();
        Calendar cal = Calendar.getInstance();

        if (year == null || month == null || day == null)
            return "";

        cal.set( Calendar.YEAR, Integer.parseInt(year) ) ;
        cal.set( Calendar.MONTH, Integer.parseInt(month)) ;
        cal.set( Calendar.DAY_OF_MONTH, Integer.parseInt(day)) ;

        cc.setTimeInMillis( cal.getTimeInMillis() ) ;

        // ChinessCalendar.YEAR 는 1~60 까지의 값만 가지고 ,
        // ChinessCalendar.EXTENDED_YEAR 는 Calendar.YEAR 값과 2637 만큼의 차이를 가진다.
        int y = cc.get(ChineseCalendar.EXTENDED_YEAR)-2637 ;
        int m = cc.get(ChineseCalendar.MONTH)+1 ;
        int d = cc.get(ChineseCalendar.DAY_OF_MONTH) ;

        StringBuffer ret = new StringBuffer() ;
        if( y < 1000 )          ret.append( "0" ) ;
        else if( y < 100 )      ret.append( "00" ) ;
        else if( y < 10 )       ret.append( "000" ) ;
        ret.append( y ) ;

        if( m < 10 ) ret.append( "0" ) ;
        ret.append( m ) ;

        if( d < 10 ) ret.append( "0" ) ;
        ret.append( d ) ;

        return ret.toString().substring(4,6)+"."+ret.toString().substring(6,8);
    }

    // 해당 달의 첫 요일을 구해서 돌려줌.
    private static int getStartDay(int year, int month) {
        int monthSum = 0;
        int leapYear = 0;
        int daySum = 1;

        for (int i = 1; i < year; i++) {
            monthSum += 365;
            if (isLeapYear(i) == true) {
                leapYear += 1;
            }
        }

        for (int j = 1; j < month; j++) {
            daySum += getLastDay(year, j);
        }

        return (monthSum + leapYear + daySum) % 7;

    }

    // 달의 마지막 일을 구함
    public static int getLastDay(int month, int year) {

        if (month == 4 || month == 6 || month == 9 || month == 11) {
            return 30;
        } else if (month == 2 && isLeapYear(year) == true) {
            return 29;
        } else if (month == 2 && isLeapYear(year) == false) {
            return 28;
        } else {
            return 31;
        }
    }

    // 해당 년도가 윤년인지 판별
    private static boolean isLeapYear(int year) {
        return (((year % 4 == 0) && (year % 100 != 0)) || (year % 400 == 0));
    }
}


CalendarHelper 수정본

package com.link2me.android.util;

import com.ibm.icu.util.ChineseCalendar;
import com.link2me.android.item.Holidays_Item;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.HashMap;


public class CalendarHelper {
    static HashMap<String, Holidays_Item> holidaysArrayList = new HashMap<String,Holidays_Item>();

    /**
     * 음력날짜를 양력날짜로 변환
     * @param 음력날짜 (yyyyMMdd)
     * @return 양력날짜 (yyyyMMdd)
     */
    public static String Lunar2Solar(String yyyymmdd) {
        ChineseCalendar cc = new ChineseCalendar();
        Calendar cal = Calendar.getInstance();

        if (yyyymmdd == null)
            return "";

        String date = yyyymmdd.trim();
        if (date.length() != 8) {
            if (date.length() == 4)
                date = date + "0101";
            else if (date.length() == 6)
                date = date + "01";
            else if (date.length() > 8)
                date = date.substring(0, 8);
            else
                return "";
        }

        cc.set(ChineseCalendar.EXTENDED_YEAR, Integer.parseInt(date.substring(0, 4)) + 2637);
        cc.set(ChineseCalendar.MONTH, Integer.parseInt(date.substring(4, 6)) - 1);
        cc.set(ChineseCalendar.DAY_OF_MONTH, Integer.parseInt(date.substring(6)));

        cal.setTimeInMillis(cc.getTimeInMillis());

        int y = cal.get(Calendar.YEAR);
        int m = cal.get(Calendar.MONTH) + 1;
        int d = cal.get(Calendar.DAY_OF_MONTH);

        StringBuffer ret = new StringBuffer();
        ret.append(String.format("%04d", y));
        ret.append(String.format("%02d", m));
        ret.append(String.format("%02d", d));

        return ret.toString();
    }

    /**
     * 양력날짜를 음력날짜로 변환
     * @param 양력날짜 (yyyyMMdd)
     * @return 음력날짜 (yyyyMMdd)
     */
    public static String Solar2Lunar(String yyyymmdd) {
        ChineseCalendar cc = new ChineseCalendar();
        Calendar cal = Calendar.getInstance();

        if (yyyymmdd == null)
            return "";

        String date = yyyymmdd.trim() ;
        if( date.length() != 8 ) {
            if( date.length() == 4 )
                date = date + "0101" ;
            else if( date.length() == 6 )
                date = date + "01" ;
            else if( date.length() > 8 )
                date = date.substring(0,8) ;
            else
                return "" ;
        }

        cal.set( Calendar.YEAR, Integer.parseInt(date.substring(0,4)) ) ;
        cal.set( Calendar.MONTH, Integer.parseInt(date.substring(4,6))-1 ) ;
        cal.set( Calendar.DAY_OF_MONTH, Integer.parseInt(date.substring(6)) ) ;

        cc.setTimeInMillis( cal.getTimeInMillis() ) ;

        // ChinessCalendar.YEAR 는 1~60 까지의 값만 가지고 ,
        // ChinessCalendar.EXTENDED_YEAR 는 Calendar.YEAR 값과 2637 만큼의 차이를 가진다.
        int y = cc.get(ChineseCalendar.EXTENDED_YEAR)-2637 ;
        int m = cc.get(ChineseCalendar.MONTH)+1 ;
        int d = cc.get(ChineseCalendar.DAY_OF_MONTH) ;

        StringBuffer ret = new StringBuffer() ;
        if( y < 1000 )          ret.append( "0" ) ;
        else if( y < 100 )      ret.append( "00" ) ;
        else if( y < 10 )       ret.append( "000" ) ;
        ret.append( y ) ;

        if( m < 10 ) ret.append( "0" ) ;
        ret.append( m ) ;

        if( d < 10 ) ret.append( "0" ) ;
        ret.append( d ) ;

        return ret.toString() ;
    }


    public static HashMap<String,Holidays_Item> holidayArray(String yyyy){
        holidaysArrayList.clear(); // 데이터 초기화
        // 양력 휴일
        addHolidaysItem(yyyy,"0101" ,"신정");
        addHolidaysItem(yyyy,"0301" ,"삼일절");
        addHolidaysItem(yyyy,"0505" ,"어린이날");
        addHolidaysItem(yyyy,"0606" ,"현충일" );
        addHolidaysItem(yyyy,"0815" ,"광복절");
        addHolidaysItem(yyyy,"1003" ,"개천절");
        addHolidaysItem(yyyy,"1009" ,"한글날");
        addHolidaysItem(yyyy,"1225" ,"성탄절");

        // 음력 휴일
        String prev_seol = String.valueOf(Integer.parseInt(Lunar2Solar(yyyy+"0101")) -1);
        addHolidaysItem(yyyy,prev_seol.substring(4) ,"");
        addHolidaysItem(yyyy,SolarDays(yyyy, "0101"),"설날");
        addHolidaysItem(yyyy,SolarDays(yyyy, "0102"),"");
        addHolidaysItem(yyyy,SolarDays(yyyy, "0408"),"석탄일");
        addHolidaysItem(yyyy,SolarDays(yyyy, "0814"),"");
        addHolidaysItem(yyyy,SolarDays(yyyy, "0815"),"추석");
        addHolidaysItem(yyyy,SolarDays(yyyy, "0816"),"");

        try {
            // 어린이날 대체공휴일 검사 : 어린이날은 토요일, 일요일인 경우 그 다음 평일을 대체공유일로 지정
            int childDayChk = WeekendValue(yyyy+"0505");
            if(childDayChk == 1) addHolidaysItem(yyyy,"0506" ,"대체공휴일");
            if(childDayChk == 7) addHolidaysItem(yyyy,"0507" ,"대체공휴일");

            // 설날 대체공휴일 검사
            if(WeekendValue(Lunar2Solar(yyyy+"0101"))==1) addHolidaysItem(yyyy,SolarDays(yyyy, "0103"),"대체공휴일");
            if(WeekendValue(Lunar2Solar(yyyy+"0101"))==2) addHolidaysItem(yyyy,SolarDays(yyyy, "0103"),"대체공휴일");
            if(WeekendValue(Lunar2Solar(yyyy+"0102"))==1) addHolidaysItem(yyyy,SolarDays(yyyy, "0103"),"대체공휴일");

            // 추석 대체공휴일 검사
            if(WeekendValue(Lunar2Solar(yyyy+"0814"))==1) addHolidaysItem(yyyy,SolarDays(yyyy, "0817"),"대체공휴일");
            if(WeekendValue(Lunar2Solar(yyyy+"0815"))==1) addHolidaysItem(yyyy,SolarDays(yyyy, "0817"),"대체공휴일");
            if(WeekendValue(Lunar2Solar(yyyy+"0816"))==1) addHolidaysItem(yyyy,SolarDays(yyyy, "0817"),"대체공휴일");
        } catch (ParseException e) {
            e.printStackTrace();
        }

        //Collections.sort(holidaysArrayList); // 오름차순 정렬

        return holidaysArrayList;
    }

    private static String SolarDays(String yyyy, String date){
        return Lunar2Solar(yyyy+date).substring(4);
    }

    private static void addHolidaysItem(String year, String date, String name ){
        Holidays_Item item = new Holidays_Item();
        item.setYear(year);
        item.setDate(date);
        item.setName(name);
        holidaysArrayList.put(date,item);
    }

    public static int WeekendValue(String date) throws ParseException {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");
        Calendar cal = Calendar.getInstance();
        cal.setTime(sdf.parse(date));
        return cal.get(Calendar.DAY_OF_WEEK);
        // Calendar.SUNDAY : 1
        // Calendar.SATURDAY : 7
    }

    /**
     * 양력날짜의 요일을 리턴
     * @param 양력날짜 (yyyyMMdd)
     * @return 요일(int)
     */
    public static int getDayOfWeek(String day) {
        int y = Integer.parseInt(day.substring(0, 4));
        int m = Integer.parseInt(day.substring(4, 6)) - 1;
        int d = Integer.parseInt(day.substring(6));
        Calendar c = Calendar.getInstance();
        c.set(y, m, d);
        return c.get(Calendar.DAY_OF_WEEK);
    }

    public static String Sol2Lun(String year, String month, String day) {
        ChineseCalendar cc = new ChineseCalendar();
        Calendar cal = Calendar.getInstance();

        if (year == null || month == null || day == null)
            return "";

        cal.set( Calendar.YEAR, Integer.parseInt(year) ) ;
        cal.set( Calendar.MONTH, Integer.parseInt(month)) ;
        cal.set( Calendar.DAY_OF_MONTH, Integer.parseInt(day)) ;

        cc.setTimeInMillis( cal.getTimeInMillis() ) ;

        // ChinessCalendar.YEAR 는 1~60 까지의 값만 가지고 ,
        // ChinessCalendar.EXTENDED_YEAR 는 Calendar.YEAR 값과 2637 만큼의 차이를 가진다.
        int y = cc.get(ChineseCalendar.EXTENDED_YEAR)-2637 ;
        int m = cc.get(ChineseCalendar.MONTH)+1 ;
        int d = cc.get(ChineseCalendar.DAY_OF_MONTH) ;

        StringBuffer ret = new StringBuffer() ;
        if( y < 1000 )          ret.append( "0" ) ;
        else if( y < 100 )      ret.append( "00" ) ;
        else if( y < 10 )       ret.append( "000" ) ;
        ret.append( y ) ;

        if( m < 10 ) ret.append( "0" ) ;
        ret.append( m ) ;

        if( d < 10 ) ret.append( "0" ) ;
        ret.append( d ) ;

        return ret.toString().substring(4,6)+"."+ret.toString().substring(6,8);
    }

    // 해당 달의 첫 요일을 구해서 돌려줌.
    private static int getStartDay(int year, int month) {
        int monthSum = 0;
        int leapYear = 0;
        int daySum = 1;

        for (int i = 1; i < year; i++) {
            monthSum += 365;
            if (isLeapYear(i) == true) {
                leapYear += 1;
            }
        }

        for (int j = 1; j < month; j++) {
            daySum += getLastDay(year, j);
        }

        return (monthSum + leapYear + daySum) % 7;

    }

    // 달의 마지막 일을 구함
    public static int getLastDay(int month, int year) {

        if (month == 4 || month == 6 || month == 9 || month == 11) {
            return 30;
        } else if (month == 2 && isLeapYear(year) == true) {
            return 29;
        } else if (month == 2 && isLeapYear(year) == false) {
            return 28;
        } else {
            return 31;
        }
    }

    // 해당 년도가 윤년인지 판별
    private static boolean isLeapYear(int year) {
        return (((year % 4 == 0) && (year % 100 != 0)) || (year % 400 == 0));
    }



블로그 이미지

Link2Me

,
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

,
728x90

Layout 을 화면에 뿌릴 MainActivity.java 코드를 아래와 같이 구현했다.


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 java.util.Calendar;
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;

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

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

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

    @Override
    public void onClick(View view) {
        switch (view.getId()) {
            case R.id.prevYear:
                year--;
                setGridCellAdapterToDate(month, year);
                break;

            case R.id.prevMonth:
                if (month <= 1) {
                    month = 12;
                    year--;
                } else {
                    month--;
                }
                setGridCellAdapterToDate(month, year);
                break;

            case R.id.currentMonth:
                cal = Calendar.getInstance(Locale.getDefault()); // 현재날짜와 시간으로 설정된다.
                month = cal.get(Calendar.MONTH) + 1; // 0 ~ 11월을 반환하므로 + 1을 해준다.
                year = cal.get(Calendar.YEAR);
                setGridCellAdapterToDate(month, year);
                break;

            case R.id.nextMonth:
                if (month > 11) {
                    month = 1;
                    year++;
                } else {
                    month++;
                }
                setGridCellAdapterToDate(month, year);
                break;

            case R.id.nextYear:
                year++;
                setGridCellAdapterToDate(month, year);
                break;

            case R.id.selectDate:
                LayoutInflater inflater = (LayoutInflater) getSystemService(LAYOUT_INFLATER_SERVICE);
                final View layout = inflater.inflate(R.layout.select_calendar_input,null);
                AlertDialog.Builder cal_confirm = new AlertDialog.Builder(mContext);
                cal_confirm.setTitle("검색할 년도 입력");
                cal_confirm.setView(layout);
                final EditText etYear = layout.findViewById(R.id.selectYear);
                final EditText etMonth = layout.findViewById(R.id.selectMonth);
                // 확인 버튼 설정
                cal_confirm.setPositiveButton("검색", new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                        String selectYear = etYear.getText().toString().trim();
                        if(selectYear.length() == 0) {
                            AlertDialog.Builder phoneNO_confirm = new AlertDialog.Builder(mContext);
                            phoneNO_confirm.setMessage("년도를 입력하세요.").setCancelable(false).setPositiveButton("확인",
                                    new DialogInterface.OnClickListener() {
                                        @Override
                                        public void onClick(DialogInterface dialog, int which) { // 'YES'
                                            dialog.dismiss();
                                        }
                                    });
                            AlertDialog alert = phoneNO_confirm.create();
                            alert.show();
                            return;
                        }

                        String selectMonth = etMonth.getText().toString().trim();
                        if(selectMonth.length() == 0) {
                            AlertDialog.Builder phoneNO_confirm = new AlertDialog.Builder(mContext);
                            phoneNO_confirm.setMessage("월(月)을 입력하세요.").setCancelable(false).setPositiveButton("확인",
                                    new DialogInterface.OnClickListener() {
                                        @Override
                                        public void onClick(DialogInterface dialog, int which) { // 'YES'
                                            dialog.dismiss();
                                        }
                                    });
                            AlertDialog alert = phoneNO_confirm.create();
                            alert.show();
                            return;
                        }
                        month = Integer.parseInt(selectMonth);
                        year = Integer.parseInt(selectYear);
                        setGridCellAdapterToDate(month, year);
                    }
                });
                cal_confirm.setNegativeButton("취소", new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                        dialog.dismiss();
                    }
                });
                cal_confirm.show();
                break;
        }
    }

    @Override
    public void onDestroy() {
        Log.d(TAG, "Destroying View ...");
        super.onDestroy();
    }
}


화면에 출력할 데이터는 GridCellAdapter 를 만들어서 뿌려주면 된다.

블로그 이미지

Link2Me

,
728x90

만들고 싶은 달력의 모습은 아래와 같다.

이미지 파일은 https://www.iconfinder.com/ 에서 free 이미지를 받아서 이미지 크기를 줄여서 사용했다.


 



AndroidManifest.xml

apply plugin: 'com.android.application'

android {
    compileSdkVersion 28


    defaultConfig {
        applicationId "com.link2me.android.calendar"
        minSdkVersion 19
        targetSdkVersion 28
        versionCode 1
        versionName "1.0"

    }

    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
        }
    }

}

dependencies {
    implementation fileTree(dir: 'libs', include: ['*.jar'])

    implementation 'androidx.appcompat:appcompat:1.1.0'
    implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
    implementation files('libs/icu4j-4_8_2.jar')
}


Android 달력 만들기 Layout 구성을 위한 XML 파일 구조다.

전년도, 이전달, 현재 월, 다음달, 다음년도, 특정 년월 검색

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:background="@color/lightgray"
    android:orientation="vertical" >

    <LinearLayout
        android:id="@+id/buttonlayout"
        android:layout_width="fill_parent"
        android:layout_height="60sp"
        android:background="@drawable/navibar_bg"
        android:gravity="left|top"
        android:height="60sp"
        android:orientation="horizontal" >

        <LinearLayout
            android:layout_width="50dp"
            android:layout_height="wrap_content"
            android:layout_gravity="center"
            android:gravity="center">

            <ImageView
                android:id="@+id/prevYear"
                android:layout_width="wrap_content"
                android:layout_height="35dp"
                android:layout_gravity="center"
                android:src="@drawable/double_arrow_left" >
            </ImageView>
        </LinearLayout>

        <LinearLayout
            android:layout_width="50dp"
            android:layout_height="wrap_content"
            android:layout_gravity="center"
            android:gravity="center">
            <ImageView
                android:id="@+id/prevMonth"
                android:layout_width="wrap_content"
                android:layout_height="35dp"
                android:layout_gravity="center"
                android:src="@drawable/arrow_left" >
            </ImageView>
        </LinearLayout>

        <TextView
            android:id="@+id/currentMonth"
            android:layout_width="fill_parent"
            android:layout_height="60sp"
            android:layout_weight="0.6"
            android:gravity="center"
            android:textAppearance="?android:attr/textAppearanceMedium"
            android:textColor="#FFFFFF" >
        </TextView>

        <LinearLayout
            android:layout_width="50dp"
            android:layout_height="wrap_content"
            android:layout_gravity="center"
            android:gravity="center">

            <ImageView
                android:id="@+id/nextMonth"
                android:layout_width="wrap_content"
                android:layout_height="35dp"
                android:layout_gravity="center"
                android:src="@drawable/arrow_right" >
            </ImageView>

        </LinearLayout>

        <LinearLayout
            android:layout_width="50dp"
            android:layout_height="wrap_content"
            android:layout_gravity="center"
            android:gravity="center">
            <ImageView
                android:id="@+id/nextYear"
                android:layout_width="wrap_content"
                android:layout_height="35dp"
                android:layout_gravity="center"
                android:src="@drawable/double_arrow_right" >
            </ImageView>
        </LinearLayout>

        <LinearLayout
            android:layout_width="50dp"
            android:layout_height="wrap_content"
            android:layout_gravity="center"
            android:gravity="center">
            <ImageView
                android:id="@+id/selectDate"
                android:layout_width="wrap_content"
                android:layout_height="35dp"
                android:layout_gravity="center"
                android:src="@drawable/box_arrow" >
            </ImageView>
        </LinearLayout>

    </LinearLayout>

    <LinearLayout
        android:layout_width="fill_parent"
        android:layout_height="30dp"
        android:background="#e0e7ee"
        android:gravity="center"
        android:orientation="horizontal">

        <TextView
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:gravity="center"
            android:text="일"
            android:textColor="#ff0000"
            android:textSize="14sp"
            android:textStyle="bold" />

        <TextView
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:gravity="center"
            android:text="월"
            android:textColor="#969a9b"
            android:textSize="14sp"
            android:textStyle="bold" />

        <TextView
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:gravity="center"
            android:text="화"
            android:textColor="#969a9b"
            android:textSize="14sp"
            android:textStyle="bold" />

        <TextView
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:gravity="center"
            android:text="수"
            android:textColor="#969a9b"
            android:textSize="14sp"
            android:textStyle="bold" />

        <TextView
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:gravity="center"
            android:text="목"
            android:textColor="#969a9b"
            android:textSize="14sp"
            android:textStyle="bold" />

        <TextView
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:gravity="center"
            android:text="금"
            android:textColor="#969a9b"
            android:textSize="14sp"
            android:textStyle="bold" />

        <TextView
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:gravity="center"
            android:text="토"
            android:textColor="#ff0000"
            android:textSize="14sp"
            android:textStyle="bold" />
    </LinearLayout>

    <GridView
        android:id="@+id/calendar"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:numColumns="7" >
    </GridView>

</LinearLayout>


select_calendar_input.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="150dp"
    android:layout_height="wrap_content"
    android:orientation="vertical">

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal">

        <TextView
            android:layout_width="50dp"
            android:layout_height="wrap_content"
            android:text="년도"
            android:layout_marginLeft="20dp"
            android:textSize="12sp" />

        <EditText
            android:id="@+id/selectYear"
            android:layout_width="match_parent"
            android:layout_height="40dp"
            android:layout_marginRight="20dp"
            android:singleLine="true"
            android:inputType="number"
            android:textSize="16sp"
            android:textColor="#000000" />

    </LinearLayout>

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal">

        <TextView
            android:layout_width="50dp"
            android:layout_height="wrap_content"
            android:layout_marginLeft="20dp"
            android:text="월(月)"
            android:textSize="12sp" />

        <EditText
            android:id="@+id/selectMonth"
            android:layout_width="match_parent"
            android:layout_height="40dp"
            android:layout_marginRight="20dp"
            android:singleLine="true"
            android:inputType="number"
            android:textSize="16sp"
            android:textColor="#000000" />

    </LinearLayout>
</LinearLayout>


블로그 이미지

Link2Me

,