오늘은 그리드 뷰에 대해서 알아보았습니다.





원래 간단한 예제를 찾아서 가져다 쓰려고 했는데, 적합한 예제도 없고, 
해서, 그리드뷰를 이용해서 기본적인 달력을 만들어 보았습니다.

결과적으로 만들어질 달력의 모습은 아래와 같습니다.

 
 


순서는 아래의 다섯단계입니다.
1. GridView selector XML 작성
2. Activity Layout XML 작성
3. 날짜 하나(Cell)에 해당하는 XML 작성
4. Adapter 작성
5. Activity Code 구현




 1. GridView selector XML 작성 

저장위치 : res/drawable
파일이름 : grideview_selector.xml


이 selector xml 파일은 그리드뷰 자체에 기본적으로 있는 padding을 없애기 위해서 작성하는 것입니다.




 2. Activity Layout XML 작성 

저장위치 : res/layout
파일이름 : gv_calendar_activity.xml


달력을 만들것이기 때문에, 그리드뷰의 컬럼의 갯수를 7로 설정합니다.





 3. 날짜 하나(Cell)에 해당하는 XML 작성 및 이미지 생성

XML 작성
저장위치 : res/layout
파일이름 : day.xml


그리드뷰도 기본적으로는 리스트뷰이기 때문에(리스트뷰를 상속받았기때문에),
리스트뷰를 커스텀하던 것 처럼, cell(리스트 뷰의 경우 row)에 해당하는 XML 파일을 작성해줍니다.



이미지 생성
저장위치 : res/drawable
파일이름 : bg_day.9.png
(나인패치를 사용한 이미지 파일)

 
 

이 이미지는 나인패치를 사용한 것으로, 날짜 셀 하나의 배경으로 사용합니다.




 4. Adapter 작성 

저장위치 : me.croute.calendarexample/adapter
파일이름 : CalendarAdapter.java


BaseAdapter를 상속받아 구현한 Calendar Adapter입니다.



 5. Activity Code 구현 

저장위치 : me.croute.calendarexample/activity
파일이름 : GVCalendarActivity.java


이제는 액티비티를 구현해 줍니다.
기본적으로 버튼들과 그리드뷰, 텍스트뷰에 대해 reference를 해주고,
데이터를 구성한 후, setAdapter를 통해서 화면에 보여줍니다.


 6. 추가적으로 필요한 데이터

저장위치 : me.croute.calendarexample/domain
파일이름 : DayInfo.java












이제 달력을 화면에 보여줄 수 있습니다.
월 이동도 가능하고, 조금만 코드를 수정한다면, 모든 기계에 보여질 수 있는 달력을 만들 수 있다라는 것입니다!!
각 요일에 대한 클릭이벤트는 Activity Java 코드에 있는 onItemClick 메소드를 구현하면 됩니다.

예제 소스코드
Posted by croute

댓글을 달아 주세요

  1. 이전 댓글 더보기
  2. 김지은 2012.09.05 23:53 신고  댓글주소  수정/삭제  댓글쓰기

    안녕하세요 이 예제를 하번 그대로 ㄸㅏ라 쳐보면서 소화시킬려고하는 학생인데요 자꾸 에러가 떠저 소스파일을 다운받아서 봣는데 Activity cannot be resolved to a type 이러한 에러들이 엄청 많이 뜨더라구요 Button도 그러구요..
    그래서 검색해서 하라는대로 이것저럿 Build Path 에서 들어가서 바꿔도 보고 해봣는데 에러가 안고쳐집니다..ㅜㅜ
    왜그러는건지 알려주세요...ㅜ0ㅜ

  3. 김지은 2012.09.06 18:02 신고  댓글주소  수정/삭제  댓글쓰기

    The method inflate(int, null) is undefined for the type LayoutInflater

    TextView cannot be resolved to a type

    LAYOUT_INFLATER_SERVICE cannot be resolved or is not a field

    The method getCount() of type CalendarAdapter<mLiInflater,LayoutInflater> must override or implement a supertype method

    The method setText(String) is undefined for the type TextView

    CalendarAdapter is a raw type. References to generic type CalendarAdapter<mLiInflater,LayoutInflater> should be parameterized

    에러코드... 붙여주기가 뭐하네요 전부다 에러가 첨부터 끝까지 에러투성이 빨간줄이에요.....ㅜㅜ 대략 내용을 보시면 이런식으로 에러가 나와있어요..ㅠㅠ

  4. 김지은 2012.10.30 00:39 신고  댓글주소  수정/삭제  댓글쓰기

    [2012-10-30 00:35:10 - GridViewCalendarExample] Android requires compiler compliance level 5.0 or 6.0. Found '1.7' instead. Please use Android Tools > Fix Project Properties.
    소스 돌려보고싶은데요...ㅜ0ㅜ 전 인디고 버전 사용하고요 인터넷 검색해보니까 .. 해달라는대로 해주면 된다고 하길래 안드로이드툴들어가서 픽스 프로젝트 프로펄티즈 클릭했는데도 안되요 ㅜㅜ
    뭐가 문제일까요 아.... 9월달에 물어보고 11월달에 와서 죄송합니당 ㅠㅠ........도와주세영 흙흙

    • Favicon of https://croute.me BlogIcon croute 2012.11.07 10:34 신고  댓글주소  수정/삭제

      자바 컴파일러 버전이 1.5(5) 이상 필요할거에요
      그래서 1.5 나 1.6으로 설정하면 되는데 1.7만 있다고 하는것 같네요.

  5. 이연희 2013.05.22 11:15 신고  댓글주소  수정/삭제  댓글쓰기

    안드로이드를 공부하는 학생입니다 ~!

    혹시 아직 이글 보신다면 좀 도와주세요 ㅜ 보면서 이해 안되는 부분이 있어서 ~

    제가 이렇게 달력을 만들어서 각 날짜를 눌러서 일정을 추가하는 어플을 만들어 보려구 하는데요

    어떻게 현재 날짜를 받아와서 각칸에 설정을 하는건지가 궁금합니다 ㅠ

    그리구 날짜를 눌러 일정을 추가하려면 어느부분에서 리스너를 달아줘야 할지 모르겠어요 도와주세요 ~~

    • Favicon of https://croute.me BlogIcon croute 2013.05.22 11:27 신고  댓글주소  수정/삭제

      날짜를 만드는 부분
      - 5. Activity Code 구현 부분을 보면, getCalendar() 라는 메소드가 있습니다. 이 메소드에서 날짜를 만들고요.

      날짜를 눌러서 일정을 추가하려면
      - 방법 1 GridView 에 setOnItemClickListener 를 설정하던가,
      - 방법 2 GridView 에 사용하는 Adapter 의 getView 부분에서 convertView 에 setOnClickListener 를 설정해야 합니다.
      - 사실상 리스트뷰와 구현부는 똑같고요, http://croute.me/519 <-- 이 포스트를 참고하면 될 것 같습니다.

      더 궁금하신게 있으시면, 블로그 댓글이나 방명록, 이메일(yhwoo.croute@gmail.com) 으로 연락주세요~ ^^

    • 이연희 2013.05.23 08:27 신고  댓글주소  수정/삭제

      너무너무 감사합니다 ~! 참고하고 해보겠습니다 감사합니당~~

  6. 질문있습니다. 2013.05.30 17:12 신고  댓글주소  수정/삭제  댓글쓰기

    예제 파일을 열어서 테스트를 해봐도, 기본적은 틀은 출력이 되는데, 안쪽의 그리드뷰는 출력이 안되더라구요.;
    (그냥 파란 배경에, 맨 위에 텍스트 뷰
    그리고 밑에 버튼이 윗부분만 살짝 보이는 상태)

    이런 경우에는 어떤 문제인건가요;;

    • Favicon of https://croute.me BlogIcon croute 2013.05.30 18:35 신고  댓글주소  수정/삭제

      어떤 문제인지 알기 굉장히 어렵죠 ㅋ

      추측해볼뿐인데요,
      날짜 데이터를 못만들어서 뿌려줄 데이터가 없으니 안보여줄수도 있고,
      레이아웃에서 orientation 이 잘못되어서 그럴수도 있고,
      Visibility 설정이 잘못되어서 그럴수도 있고,
      Adapter 의 getView 에서 Item들의 view 를 만드는 부분이 잘못되어서 그럴수도 있고요.
      기타 등등 무궁무진 합니다. ㅋ
      코드를 보거나, log를 보면 좀 더 특정 시킬순 있겠죠.

    • Favicon of https://croute.me BlogIcon croute 2013.05.30 18:54 신고  댓글주소  수정/삭제

      저도 다시 다운받아서 이뮬레이터에서 실행해 봤는데...
      해상도 깨지는거 빼고는(예전에 만든거라 해상도 적용은.. 쿨럭...)
      잘 되네요..... 음....

  7. 안녕하세요 2013.07.02 11:00 신고  댓글주소  수정/삭제  댓글쓰기

    저도 보면서 공부를 하고있는데요.

    글자간격 사이가 너무 길어서 줄일려고 하는데.... calendar_day부분을 줄여도 소용이 없고..
    네모박스를 정사각형으로 만들고싶은데
    어딜줄여야될까여.. = _ =;

  8. 2013.07.14 23:06  댓글주소  수정/삭제  댓글쓰기

    비밀댓글입니다

  9. 2013.07.14 23:11  댓글주소  수정/삭제  댓글쓰기

    비밀댓글입니다

  10. BlogIcon 김두회 2013.07.16 19:41 신고  댓글주소  수정/삭제  댓글쓰기

    이 예제코드들 마음대루 사용해도 될까요 ~ ^__^!?

  11. BlogIcon 박장원 2013.08.01 11:55 신고  댓글주소  수정/삭제  댓글쓰기

    질문이요 ㅠㅠ
    swipe 제스처로 다음달이나 지난달로 넘어가게 만들고싶은데요
    swipe제스처를 넣으면 다른부분에서는 인식하는데 gridview 안에서는 제스처 인식이안되네요
    어떻게 해야할까요??

    • Favicon of https://croute.me BlogIcon croute 2013.08.01 12:49 신고  댓글주소  수정/삭제

      음..
      사실상 하나의 그리드 뷰에서, 스와이프 액션으로
      데이터만 교체하고 싶다는거죠?

      아니면 실제로 물리적인 그리드뷰를 적어도 3개(왼쪽 현재보이는부분 오른쪽)을 사용하시려는 건가요?

      물리적으로 3개를 두려면(이렇게 할 이유는 없지만)
      뷰 페이저를 사용하시면 될것 같고,

      물리적으로는 1개의 그리드뷰만 사용하지만,
      스와이프 액션으로 데이터만 교체하려 한다면,
      어쩔 수 없이 onTouch 부분을 구현하고,
      그 부분에서 GirdView 의 액션을 인터셉트 하는 수밖에는..

      GridView.requestDisallowInterceptTouchEvent(true);
      GridView.requestDisallowInterceptTouchEvent(false);

      같은 방식으로요.

      이미 swipe 제스쳐를 붙이셨다니,
      swipe 액션이 시작되면 그리드뷰의 이벤트를 인터셉트하고 끝나면 풀어주는 방식으로 하면 될거에요.

  12. 박장원 2013.08.01 13:20 신고  댓글주소  수정/삭제  댓글쓰기

    자세한 설명 감사합니다.. 하지만 너무어렵군요 이해하기가요ㅠㅠ

    일단 1개의 그리드뷰를 가지고 진행을 할거구요

    swipe 액션이 인식되면, gridview가인식이되면 다음달 어뎁터를 다시얻어서 셋어뎁터를 할려고하는데요
    문제는...

    아예 인식자체가 안됩니다 gridview 위에서 swipe가요...

    지금 전체화면에서 gridview빼고는 swipe인식되면 토스트메세지가 뜨는데요 딱 gridview에서만 토스트
    메세지가 안뜹니다...

    어떻게해야할까요..ㅠㅠ부탁드립니다ㅠㅠㅠㅠㅠㅠㅠㅠ

  13. 박장원 2013.08.01 13:22 신고  댓글주소  수정/삭제  댓글쓰기

    참고로 혹시 필요하실까봐 swipe 액션 지금 코딩되어있는 것 올려봅니다.
    Activity 안에서 코딩이구요

    public boolean onTouchEvent(MotionEvent e){
    return detector.onTouchEvent(e);
    }

    final static int DISTANCE = 200;
    final static int VELOCITY = 350;

    OnGestureListener gestureListener = new OnGestureListener(){
    public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
    if(e1.getX()-e2.getX() < DISTANCE && Math.abs(velocityX) > VELOCITY){
    ToastOut("좌->우";);
    }
    if(e2.getX()-e1.getX() < DISTANCE && Math.abs(velocityX) > VELOCITY){
    ToastOut("우->좌";);
    }
    return false;
    }

    public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) {
    return false;
    }

    public void onLongPress(MotionEvent e) {
    }

    public void onShowPress(MotionEvent e) {
    }

    @Override
    public boolean onSingleTapUp(MotionEvent e) {
    return false;
    }

    public boolean onDown(MotionEvent e) {
    return false;
    }
    };

  14. 2013.08.05 22:34  댓글주소  수정/삭제  댓글쓰기

    비밀댓글입니다

  15. Favicon of http://binaries.me BlogIcon binaries 2013.12.20 11:46 신고  댓글주소  수정/삭제  댓글쓰기

    좋은 예제 감사합니다.
    덕분에 조금 편한 상태에서 작업할수 있게 되었습니다.

  16. Favicon of http://blog.naver.com/jaeha1223 BlogIcon JaeHa 2014.03.13 21:28 신고  댓글주소  수정/삭제  댓글쓰기

    감사합니다. 프레그먼트형태로 만들려고 하는데 참고 많이 될것 같습니다.

  17. BlogIcon alstjddl90 2014.07.13 16:52 신고  댓글주소  수정/삭제  댓글쓰기

    모든 핸드폰에 사용 하려고 한다면 비율을 어떻게 맞춰야 하나요 ??

    • Favicon of https://croute.me BlogIcon croute 2014.07.14 12:34 신고  댓글주소  수정/삭제

      사실 깔끔하게 맞추기 위해선 자바 코드에서 화면 크기를 잰 후, 컬럼 갯수로 나눠서 작업하는게 제일 좋기는 합니다. ㅎㅎ

  18. BlogIcon Lee 2014.10.08 04:21 신고  댓글주소  수정/삭제  댓글쓰기

    안녕하세요. 달력 만드는데에 도움을 얻고자 코드를 살펴 본 학생입니다. 이 글을 보실지는 모르겠지만 질문하나 드려봅니다.
    달력을 켰을 때 오늘 날짜에 표시가 되어있게 만들어 보고 싶은데(예를들어, 배경색이 칠해져 있다거나 동그라미 표시가 되어있다거나) 어떻게 건드려야 할 지 감이 오지 않아서요. 도움 좀 부탁드려도 될까요?!

  19. ^^ 2016.10.02 02:12 신고  댓글주소  수정/삭제  댓글쓰기

    잘 보고 갑니다.

  20. 행인 2016.11.27 16:20 신고  댓글주소  수정/삭제  댓글쓰기

    시간이 오래지났지만 혹시라도 제 댓글보시면 답변 부탁드려요.
    캘릭더뷰에대해서 공부하고있는데 이 소스에서는 오늘해당 날짜에대해서 표시되는게 없더군요..
    그래서 다른 소스보면서 계속 시도해보고있는데 도저히 안되네요...
    http://heum-story.tistory.com/6 <=에서 해당날짜 표시되는게 있어서 보고 변형해서 하고있기는한데..안되네요
    코드 어떻게 짜야하나요?

  21. 행인입니다 2017.12.31 16:27 신고  댓글주소  수정/삭제  댓글쓰기

    핸드폰 마다 화면 사이즈가 달라서 텍스트 열간격, 행간격 신경써야 되니 따로 자동계산하는 코드 작성하시거나,
    핸드폰 마다 화면 사이즈가 나온 사이트를 넣었으니 참고하세요~ -> http://screensiz.es/
    바꿀위치는 getCellWidthDP() 메소드 부터입니다
    엄청해매다가 찾아서 공유합니다.