본문 바로가기
AndroidStudio/Kotlin

[Android Studio / Kotlin] RecyclerView Calendar 구현하기

by D.B_18 2021. 12. 30.

오늘은 RecyclerView를 이용하여 간단하게 달력을 구현해보도록 하겠습니다. 가로 방향으로 슬라이드하면 날짜를 볼 수 있는 형태로 구현했습니다.

우선 달력이 나오도록 할 화면에 recyclerView를 추가합니다.

 

fragment_calender.xml

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

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

        <Button
            android:id="@+id/today_btn"
            android:layout_width="120dp"
            android:layout_height="wrap_content"
            android:background="#00FFFFFF"
            android:text="TODAY"
            android:textColor="#BDC0BA" />

        <TextView
            android:id="@+id/month_year_tv"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:gravity="center"
            android:text="AUGUST 2021"
            android:textColor="#000000"
            android:textSize="16sp" />

        <Button
            android:id="@+id/add_btn"
            android:layout_width="120dp"
            android:layout_height="wrap_content"
            android:background="#00FFFFFF"
            android:text="ADD TASK"
            android:textColor="#BDC0BA" />
    </LinearLayout>

    <androidx.recyclerview.widget.RecyclerView
        android:id="@+id/calendar_list"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:overScrollMode="never"/>

</LinearLayout>

 

그리고 나서, recyclerView에 반복적으로 나오도록 할 view를 만들어줍니다.

calendar_cell.xml

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

    <TextView
        android:id="@+id/day_cell"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="MON" />

    <TextView
        android:id="@+id/date_cell"
        android:layout_width="25dp"
        android:layout_height="25dp"
        android:layout_marginTop="10dp"
        android:gravity="center"
        android:text="1" />
</LinearLayout>

화면을 모두 만들었으면, 달력에 들어갈 calendar_cell의 하나하나를 관리할 Adapter를 생성합니다.

Date.kt

calendar_cell에 필요한 요일과 날짜를 갖고 있는 객체입니다.

class Date(day: String, date: String){
    var day: String = day // 요일
    var date: String = date // 날짜
}

CalendarAdapter.kt

RecyclerView.Adapter<CalendarAdapter.ViewHolder>를 상속받아서 Adapter를 생성했습니다.

ViewHolder에는 calendar_cell에 있는 요일을 나타내는 textView와 날짜를 나타내는 textView를 선언합니다.

onBindViewHolder에서 ViewHolder에 선언한 날짜와 요일(Date)을 ArrayList로 받아온 날짜와 요일(Date)로 초기화합니다.

class CalendarAdapter(private val dataSet: ArrayList<Date>): RecyclerView.Adapter<CalendarAdapter.ViewHolder>() {
    var drawable: Drawable? = null
    private lateinit var itemClickListener : OnItemClickListener

    class ViewHolder(view: View): RecyclerView.ViewHolder(view) {
        val dateTv: TextView = view.findViewById(R.id.date_cell)
        val dayTv: TextView = view.findViewById(R.id.day_cell)
    }

    override fun onCreateViewHolder(viewGroup: ViewGroup, viewType: Int): ViewHolder {
        val view = LayoutInflater.from(viewGroup.context).inflate(R.layout.calendar_cell, viewGroup, false)

        drawable = ContextCompat.getDrawable(view.context, R.drawable.round)
        return ViewHolder(view)
    }

    override fun onBindViewHolder(holder: ViewHolder, position: Int) {
        holder.dateTv.text = dataSet[position].date
        holder.dayTv.text = dataSet[position].day
    }

    override fun getItemCount() = dataSet.size
}

CalendarFragment.kt

recyclerView가 있는 Fragment 클래스에서 recyclerView에 보여줄 리스트를 만들고, Adapter를 등록해줍니다.

class CalendarFragment : Fragment() {
    val itemList = arrayListOf<Date>()
    val listAdapter = CalendarAdapter(itemList)
    lateinit var calendarList: RecyclerView
    lateinit var mLayoutManager: LinearLayoutManager

    override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {

        val view = inflater.inflate(R.layout.fragment_calendar, container, false)
        calendarList = view.findViewById(R.id.calendar_list)
        mLayoutManager = LinearLayoutManager(view.context)

        // recyclerView orientation (가로 방향 스크롤 설정)
        mLayoutManager.orientation = LinearLayoutManager.HORIZONTAL
        calendarList.layoutManager = mLayoutManager

        setListView()

        return view
    }

	// list(날짜, 요일)를 만들고, adapter를 등록하는 메소드
    private fun setListView() {
    	// 현재 달의 마지막 날짜
    	val lastDayOfMonth = LocalDate.now().with(TemporalAdjusters.lastDayOfMonth())
        lastDayOfMonth.format(DateTimeFormatter.ofPattern("dd"))

        for(i: Int in 1..lastDayOfMonth) {
            val date = LocalDate.of(LocalDate.now().year, LocalDate.now().month, i)
            val dayOfWeek: DayOfWeek = date.dayOfWeek
            dayOfWeek.getDisplayName(TextStyle.SHORT, Locale.US)

            itemList.add(Date(dayOfWeek.toString().substring(0, 3), i.toString()))
        }
        calendarList.adapter = listAdapter
    }
}

 

여기까지 RecyclerView를 이용하여 간단한 달력을 구현해봤습니다..!

728x90
반응형