ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 안드로이드 달력 예제( android custom calendar example )
    Android/달력 2019. 3. 5. 08:24




    날짜 선택 가능한 달력 예제입니다. 

    다음 링크에 있는 캘린더 라이브러리를 사용합니다. 


    https://github.com/ApplikeySolutions/CosmoCalendar



    2018.07.27   최초작성

    ~~~~~~~~

    2020. 01. 06  androidx로 변경




    다음처럼 동작합니다.



    1. single을 선택한 경우 날짜를 하나씩 선택할 수 있습니다. 

    오른쪽 위에 있는 아이콘을 터치하면 선택한 날짜를 확인할 수 있습니다. 

    선택 취소는 아이콘을 터치하여 할 수 있습니다. 





    2. multiple을 선택한 경우  다수의 날짜를 선택할 수 있습니다. 





    3. range를 선택한 경우 연속적인 날짜를 선택할 수 있습니다. 





    4. none을 선택한 경우 날짜 선택을 못하게 합니다. 






    다음 과정으로 예제를 테스트할 수 있습니다.  새로운 프로젝트를 빈 액티비티로 생성한 후 진행합니다.  


    1. build.gradle에 필요한 라이브러리를 추가합니다. 

    com.github.applikeysolutions:cosmocalendar를 먼저 추가하고 필요하면  'androidx.recyclerview:recyclerview:1.0.0'를 추가하세요.

    사용하는 안드로이드 버전에 따라 추가되는 라이브러리가 다를 수 있습니다.


    dependencies {

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

        implementation 'androidx.appcompat:appcompat:1.1.0'

        implementation 'androidx.constraintlayout:constraintlayout:1.1.3'

        implementation 'com.github.applikeysolutions:cosmocalendar:1.0.4'

        implementation 'androidx.recyclerview:recyclerview:1.0.0'

        testImplementation 'junit:junit:4.12'

        androidTestImplementation 'androidx.test.ext:junit:1.1.0'

        androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0'

    }





    2. 타이틀바가 안보이도록 styles.xml을 수정합니다.


    <resources>

        <!-- Base application theme. -->
        <style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
            <!-- Customize your theme here. -->
            <item name="colorPrimary">@color/colorPrimary</item>
            <item name="colorPrimaryDark">@color/colorPrimaryDark</item>
            <item name="colorAccent">@color/colorAccent</item>
           <!-- No Title Bar-->
            <item name="windowActionBar">false</item>
            <item name="windowNoTitle">true</item>
        </style>

    </resources>




    3. 프로젝트 창의 res 폴더에에 menu 폴더를 추가하고 menu.xml 파일을 추가합니다.



    <?xml version="1.0" encoding="utf-8"?>
    <menu xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:app="http://schemas.android.com/apk/res-auto">

        <item
            android:id="@+id/clear_selections"
            android:title="clear_selections"
            android:icon="@android:drawable/ic_menu_delete"
            app:showAsAction="always" />

        <item
            android:id="@+id/show_selections"
            android:title="show_selections"
            android:icon="@android:drawable/ic_menu_info_details"
            app:showAsAction="always" />

    </menu>




    4. activity_main.xml 파일을 다음 내용으로 대체합니다. 


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

        <androidx.appcompat.widget.Toolbar
            android:id="@+id/toolbar"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:minHeight="?attr/actionBarSize" />

        <com.applikeysolutions.cosmocalendar.view.CalendarView
            android:id="@+id/calendar_view"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_above="@+id/ll_settings"
            android:layout_below="@id/toolbar"/>

        <LinearLayout
            android:id="@+id/ll_settings"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_alignParentBottom="true"
            android:orientation="horizontal">

            <RadioGroup
                android:id="@+id/rg_selection_type"
                android:layout_width="0dp"
                android:layout_height="wrap_content"
                android:layout_weight="1"
                android:checkedButton="@+id/rb_single">

                <RadioButton
                    android:id="@+id/rb_single"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:text="single" />

                <RadioButton
                    android:id="@+id/rb_multiple"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:text="multiple" />

                <RadioButton
                    android:id="@+id/rb_range"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:text="range" />

                <RadioButton
                    android:id="@+id/rb_none"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:text="none" />

            </RadioGroup>

        </LinearLayout>

    </RelativeLayout>




    5. MainActivity.java 파일을 다음 코드로 대체합니다. ]


    "is not accessible from java.lang.Class<android.app.AppComponentFactory>"에러가 나서 class MainActivity 앞에 public를 추가했습니다. 


    import android.os.Bundle;
    import androidx.annotation.IdRes;
    import androidx.annotation.Nullable;
    import androidx.appcompat.app.AppCompatActivity;
    import androidx.recyclerview.widget.OrientationHelper;
    import androidx.appcompat.widget.Toolbar;
    import android.view.Menu;
    import android.view.MenuInflater;
    import android.view.MenuItem;
    import android.widget.RadioGroup;
    import android.widget.Toast;


    import com.applikeysolutions.cosmocalendar.utils.SelectionType;
    import com.applikeysolutions.cosmocalendar.view.CalendarView;

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


    public class MainActivity extends AppCompatActivity implements RadioGroup.OnCheckedChangeListener {

        private CalendarView calendarView;



        @Override
        protected void onCreate(@Nullable Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);

            setSupportActionBar((Toolbar) findViewById(R.id.toolbar));

            initViews();
        }

        private void initViews() {
            calendarView = (CalendarView) findViewById(R.id.calendar_view);
            calendarView.setCalendarOrientation(OrientationHelper.HORIZONTAL);

            ((RadioGroup) findViewById(R.id.rg_selection_type)).setOnCheckedChangeListener(this);
        }



        @Override
        public boolean onCreateOptionsMenu(Menu menu) {
            MenuInflater inflater = getMenuInflater();
            inflater.inflate(R.menu.menu, menu);
            return true;
        }

        @Override
        public boolean onOptionsItemSelected(MenuItem item) {
            switch (item.getItemId()) {

                case R.id.clear_selections:
                    clearSelectionsMenuClick();
                    return true;

                case R.id.show_selections:
                    List<Calendar> days = calendarView.getSelectedDates();

                    String result="";
                    for( int i=0; i<days.size(); i++)
                    {
                        Calendar calendar = days.get(i);
                        final int day = calendar.get(Calendar.DAY_OF_MONTH);
                        final int month = calendar.get(Calendar.MONTH);
                        final int year = calendar.get(Calendar.YEAR);
                        String week = new SimpleDateFormat("EE").format(calendar.getTime());
                        String day_full = year + "년 "+ (month+1)  + "월 " + day + "일 " + week + "요일";
                        result += (day_full + "\n");
                    }
                    Toast.makeText(MainActivity.this, result, Toast.LENGTH_LONG).show();
                    return true;

                default:
                    return super.onOptionsItemSelected(item);
            }
        }




        private void clearSelectionsMenuClick() {
            calendarView.clearSelections();

        }


        @Override
        public void onCheckedChanged(RadioGroup group, @IdRes int checkedId) {
            clearSelectionsMenuClick();
            switch (checkedId) {

                case R.id.rb_single:
                    calendarView.setSelectionType(SelectionType.SINGLE);
                    break;

                case R.id.rb_multiple:
                    calendarView.setSelectionType(SelectionType.MULTIPLE);
                    break;

                case R.id.rb_range:
                    calendarView.setSelectionType(SelectionType.RANGE);
                    break;

                case R.id.rb_none:
                    calendarView.setSelectionType(SelectionType.NONE);
                    break;
            }
        }
    }





    포스트 작성시에는 문제 없었지만 이후 문제가 생길 수 있습니다.
    댓글로 알려주시면 빠른 시일내에 답변을 드리겠습니다.

    여러분의 응원으로 좋은 컨텐츠가 만들어집니다. 지금 본 내용이 도움이 되었다면 유튜브 구독 부탁드립니다. 감사합니다 : )

    유튜브 구독하기


    댓글 19

    • 오훈석 2019.07.14 20:39


      Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'void com.applikeysolutions.cosmocalendar.view.CalendarView.setCalendarOrientation(int)' on a null object reference
      at com.example.hanieum.HospitalReservationControl.onCreate(HospitalReservationControl.java:35)
      켈린더 코드 그대로 했는데 이 오류가 나와서 어떻게 해야 될지 모르겠습니다.

      calendar.setCalendarOrientation(OrientationHelper.HORIZONTAL);
      이 부분이 오류가 납니다

      • Favicon of https://webnautes.tistory.com BlogIcon webnautes 2019.07.14 20:50 신고


        다음줄에서 리소스를 가져오는 부분을 검토해보세요.
        레이아웃의 리소스를 확인해보세요.

        calendarView = (CalendarView) findViewById(R.id.calendar_view);

    • 2019.08.01 12:32


      비밀댓글입니다

    • 도와주세요 2019.11.04 12:46


      GITHUB에서 받아온 캘린더의
      월 , 요일 등이 영어로 되어있는데,
      이것을 한글로 바꿀 때 어떤 파일을 수정해야하는지 알 수 있을까요.ㅠㅠㅠ

    • 부탁드려용 2019.11.13 00:07


      오류는 안뜨는데 왜 avd에 실행되다가 말까요 ㅠ

    • .. 2019.11.13 14:44


      혹시 import android.support.annotation.IdRes;
      import android.support.annotation.Nullable; 대신
      import androidx.annotation.IdRes;
      import androidx.annotation.Nullable;

      import androidx.annotation.IdRes;
      import androidx.annotation.Nullable;
      이걸 사용하면 안되나요?

      • Favicon of https://webnautes.tistory.com BlogIcon webnautes 2019.11.13 21:19 신고


        맞습니다.

        다음 링크를 보면 패키지 이름이 androidx에서 어떻게 바뀌었는지 알려줍니다.

        https://developer.android.com/jetpack/androidx/migrate/class-mappings

    • .. 2019.11.23 17:19


      선택한 달력날짜를 어떻게 불러오나요ㅠㅠ
      Toast.maketext도 되지않네요....

    • 김전기 2019.12.01 16:03


      ERROR: Could not find method api() for arguments [directory 'libs'] on object of type org.gradle.api.internal.artifacts.dsl.dependencies.DefaultDependencyHandler.
      이런 에러가 빌드할때 뜨는데 해결할 방법이 있을까요

      • Favicon of https://webnautes.tistory.com BlogIcon webnautes 2019.12.01 18:43 신고


        androidx로 변경해보았는데 실행되는데 문제가 있어보입니다. 다음과 같은 에러로 진행이 안되네요

        다른 달력 라이브러리를 사용해야 할 듯합니다.


        java.lang.RuntimeException: Unable to instantiate activity ComponentInfo{com.tistory.webnautes.myapplication/com.tistory.webnautes.myapplication.MainActivity}: java.lang.IllegalAccessException: java.lang.Class<com.tistory.webnautes.myapplication.MainActivity> is not accessible from java.lang.Class<android.app.AppComponentFactory>

    • 제발도와주세요 2020.01.06 20:39


      바쁘신데 죄송합니다. 다음이 아니라 GITHUB에서 받아온 캘린더의 월(달), 요일 등이 영어로 되어있는걸 한글로 바꿀때, 캘린더의 Locale을 한글로 바꾸는 방법을 찾아보라고 하셔서 찾아보고있는데, 도저히 감이 안와서 그러는데 조금만 알려주실수 있나여?
      calendarView의 어느부분이랑 연결해야 되는지도 모르겠습니다...

      • Favicon of https://webnautes.tistory.com BlogIcon webnautes 2020.01.06 20:49 신고


        본 포스트에 있는 게 아니라 다른 깃허브에서 가져온 거에 대해 물어본건가요?

        그런거라면 라이브러리에 따라서는 한글로 변환이 불가능한 경우도 있었던 듯합니다.

      • 제발도와주세요 2020.01.06 21:00


        본포스트에 있는겁니다. 포스트에있는 캘린더라이브러리 주소에가서 여러번보았느데도 감이 안잡히네요..

      • Favicon of https://webnautes.tistory.com BlogIcon webnautes 2020.01.06 21:53 신고


        폰이 한글이면 달력도 한글로 나오는 듯합니다.

      • 제발도와주세요 2020.01.06 22:03


        핸드폰에 따라 달라진다니.. 바쁘실텐데 답변해주셔서 정말 감사합니다.

Designed by Tistory.