코코딩딩

[안드로이드 / android] 달력 라이브러리( prolificinteractive/material-calendarview ) 본문

일단기록/매일기록

[안드로이드 / android] 달력 라이브러리( prolificinteractive/material-calendarview )

겟츄 2022. 5. 3. 15:30

 

 

달력을 구현하기 위해 직접 코드를 치는 것은 퀄리티와 시간적인 이유로 난이도가 있다고 판단되어 라이브러리를 사용해 달력을 구현하고자 한다.

 

 


 

 

prolificinteractive material-calendarview

 

 

사용할 라이브러리는 깃허브에 올라와 있는 라이브러리를 사용할 것이다. 자세한 사용방법과 다양한 사용자가 질문한 내용들이 있기 때문에 필요한 기능이 있으면 검색을 하면 어느정도 찾을 수 있다.

 

https://github.com/prolificinteractive/material-calendarview

 

 

gradle

 

 

//calendar
implementation 'com.github.prolificinteractive:material-calendarview:2.0.1'
implementation 'com.jakewharton.threetenabp:threetenabp:1.2.1'

 

 

필자의 경우 프로젝트를 생성하면 gradle의 버전은 7.2 였고 플러그인의 버전은 7.1.2 였는데 위와 같이 라이브러리를 추가만 할 경우 빌드를 할 수 없었다. github에 있는 라이브러리를 받아오기 위해서는 jitpack의 도움이 필요하다.

 

 

// settings.gradle

pluginManagement {
    repositories {
        gradlePluginPortal()
        google()
        mavenCentral()
    }
}
dependencyResolutionManagement {
    repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
    repositories {
        google()
        mavenCentral()
        maven { url 'https://jitpack.io' }
    }
}
rootProject.name = "CalendarTest"
include ':app'

 

 

위와 같이 maven { url 'https://jitpack.io' } 를 추가해주어야한다. 빌드하는데 에러가 또 뜬다면 gradle.properties에

android.enableJetifier=true 를 추가해준다.

 

 

activity_main.xml

 

 

<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools">
    <androidx.constraintlayout.widget.ConstraintLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        tools:context=".MainActivity">

        <com.prolificinteractive.materialcalendarview.MaterialCalendarView
            android:id="@+id/calendarView"
            android:layout_width="match_parent"
            android:layout_height="370.5dp"
            app:mcv_tileSize="53dp"
            android:layout_marginTop="32dp"
            app:mcv_selectionColor="@color/black"
            app:mcv_showOtherDates="all" />

    </androidx.constraintlayout.widget.ConstraintLayout>
</layout>

 

 

위와 같이 레이아웃xml 에 달력을 만들어서 사용하면 되는데 이곳에서 간단한 사항들을 컨트롤 할 수 있다. 자세한 사항은 제작자의 github에 들어가면 확인할 수 있다.

 

 

// 날짜 선택시 색 변경
app:mcv_selectionColor="@color/black"
// 날짜 선택 불가능하게 변경
app:mcv_selectionMode="none"
// 날짜 한칸 블럭의 크기 조절
app:mcv_tileSize="53dp"
// 월 변경 화살표 표시 이미지 변경
app:mcv_leftArrow="@mipmap/btn_later_bg"
app:mcv_rightArrow="@mipmap/btn_next_bg"

 

 

Decorator를 이용해 날짜에 원 표시하기

 

 

출석 체크와 같이 달력에 무언가 한 날짜에 원 표시를 하기 위한 기능을 구현할 것이다. 우선 색을 변경해주는 Decorator클래스를 만든 후 ArrayList에 표시할 날짜들을 담아 넣어줄 것이다.

 

 

Decorator 클래스

import android.app.Activity;
import android.graphics.drawable.Drawable;
import android.widget.TextView;

import com.prolificinteractive.materialcalendarview.CalendarDay;
import com.prolificinteractive.materialcalendarview.DayViewDecorator;
import com.prolificinteractive.materialcalendarview.DayViewFacade;

import java.util.Collection;
import java.util.HashSet;

public class Decorator implements DayViewDecorator {

    private final Drawable drawable;
    private int color;
    private HashSet<CalendarDay> dates;
    private TextView textView;
    public Decorator(Collection<CalendarDay> dates, Activity context) {
        drawable = context.getDrawable(R.drawable.calendar_background);

        this.dates = new HashSet<>(dates);
    }

    @Override
    public boolean shouldDecorate(CalendarDay day){
        return dates.contains(day);
    }

    @Override
    public void decorate(DayViewFacade view) {
        view.setSelectionDrawable(drawable);
    }

}

 

 

위와 같은 데코레이터를 main에서 사용하면 적용 된 날짜에 drawable에 있는 calendar_background가 적용된다.

 

 

MainActivity

 

 

import androidx.appcompat.app.AppCompatActivity;
import androidx.databinding.DataBindingUtil;

import android.content.Context;
import android.os.Bundle;
import android.view.View;

import com.example.calendartest.databinding.ActivityMainBinding;
import com.prolificinteractive.materialcalendarview.CalendarDay;
import com.prolificinteractive.materialcalendarview.MaterialCalendarView;

import java.util.ArrayList;

public class MainActivity extends AppCompatActivity {

    ActivityMainBinding binding;
    private MaterialCalendarView calendar;
    public Context context;
    private ArrayList<CalendarDay> calendarDayList = new ArrayList<>();

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        //바인딩
        binding = DataBindingUtil.setContentView(this,R.layout.activity_main);
        calendar = binding.calendarView;
        MainActivity activity = this;
        View view = binding.getRoot();
        
	//색칠할 날짜를 calendarDayList에 추가
        calendarDayList.add(CalendarDay.from(2022,05,25));
        calendarDayList.add(CalendarDay.from(2022,05,24));
        calendarDayList.add(CalendarDay.from(2022,05,23));
        
        // 오늘날짜 선택
        calendar.setSelectedDate(CalendarDay.today());
	// 데코레이터
        Decorator decorator = new Decorator(calendarDayList,activity);
        binding.calendarView.addDecorator(decorator);
    }
}

 

 

위와 같이 자신이 색을 칠하고 싶은 날짜를 list에 넣어 decorator를 사용하면 아래와 같은 화면이 나온다.

 

 

오늘날짜가 자동으로 선택된 화면

 

 

24일을 클릭하면 위와같이 된다.

 

 

calendar_background.xml

 

 

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


    <item
        android:state_pressed="true"
        android:drawable="@drawable/calendar_not_select_backgorund"></item>

    <item
        android:state_checked="true"
        android:drawable="@drawable/calendar_select_background"></item>
    <item android:drawable="@drawable/calendar_not_select_backgorund"></item>
</selector>

 

 

각각 select 됬을 때(색이 꽉찬 원)와 아닐 때(테두리만 있는 원) 의 xml도 아래와 같이 만들어주어야 한다.

 

 

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

    <item>
        <shape
            xmlns:android="http://schemas.android.com/apk/res/android"
            android:shape="rectangle">
            <solid android:color="@android:color/transparent" />
            <corners
                android:radius="250dp"/>
            <stroke
                android:width="1.5dp"
                android:color="#000000" />
        </shape>
    </item>

</layer-list>

 

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

    <item>
        <shape
            xmlns:android="http://schemas.android.com/apk/res/android"
            android:shape="rectangle">
            <solid android:color="#000000" />
            <corners
                android:radius="250dp"/>
            <stroke
                android:width="3dp"
                android:color="#000000" />
        </shape>
    </item>


</layer-list>