実現したいこと
見た目や操作などを好きにカスタマイズしたいので、リサイクラービューとViewPager2を使ってカレンダーを作成しました。
過去未来何年分でもページスクロールによってカレンダーを表示できるようにしたいと考えているのですが、なかなか上手く表示させることができません。
以下のようなコードで、現在カレンダーを画面に表示させています。
実装はこの記事を参考にしています。
・カレンダーの表示
kotlin
1 2class CalendarFragment(private val currentYear: Int, private val currentMonth: Int, val currentDay: Int) : Fragment() { 3 4 override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? { 5 return inflater.inflate(R.layout.fragment_calendar, container, false) 6 } 7 8 override fun onStart() { 9 super.onStart() 10 val text = "${currentYear}年${currentMonth}月" 11 current_year_month.text = text 12 13 calendar_view.layoutManager = GridLayoutManager(activity, 7) 14 calendar_view.adapter = CalendarAdapter((activity as MainActivity).calendarItems) 15 createCalendar() 16 } 17 18 private fun createCalendar() { 19 val calendar = Calendar.getInstance() 20 21 val main = activity!! as MainActivity 22 main.currentYear = currentYear 23 main.currentMonth = currentMonth 24 val dayOfMonth = calendar.getActualMaximum(Calendar.DATE) 25 main.calendarItems.clear() 26 for(day in 1..dayOfMonth) { 27 val map = mutableMapOf<String, Any>() 28 map["day"] = day 29 calendar.set(currentYear, currentMonth - 1, day) 30 val week = calendar.get(Calendar.DAY_OF_WEEK) 31 map["dayOfWeek"] = week 32 main.calendarItems.add(map) 33 } 34 val previousMonthDays = main.calendarItems[0]["dayOfWeek"] as Int - 1 35 if(previousMonthDays != 0) { 36 for (count in 1..previousMonthDays) { 37 val map = mutableMapOf<String, Any>("day" to "", "dayOfWeek" to "") 38 main.calendarItems.add(0, map) 39 } 40 } 41 calendar_view.adapter?.notifyDataSetChanged() 42 calendar.clear() 43 } 44 45 private inner class DateCell(view: View): RecyclerView.ViewHolder(view) { 46 var cell: LinearLayout = view.cell 47 var date: TextView = view.tv_date 48 var memo: TextView = view.tv_memo 49 } 50 51 private inner class CalendarAdapter(val items: MutableList<MutableMap<String,Any>>) : RecyclerView.Adapter<DateCell>() { 52 override fun getItemCount(): Int { 53 return items.size 54 } 55 56 override fun onBindViewHolder(holder: DateCell, position: Int) { 57 val item = items[position] 58 holder.date.text = item["day"].toString() 59 if(currentDay.toString() == item["day"].toString()) { 60 holder.date.setTextColor(Color.parseColor("#ff7f50")) 61 }else{ 62 holder.date.setTextColor(Color.BLACK) 63 } 64 } 65 66 override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): DateCell { 67 return DateCell(layoutInflater.inflate(R.layout.date_cell,parent,false)) 68 } 69 } 70 71
そしてこのカレンダーを表示するページを実装しているのが以下のコードです。
こちらはこのページの記事を参考にしました。
Kotlin
1 2class MainActivity : AppCompatActivity() { 3 4 val calendarItems: MutableList<MutableMap<String,Any>> = mutableListOf() 5 var currentYear = 0 6 var currentMonth = 0 7 var currentDay = 0 8 9 override fun onCreate(savedInstanceState: Bundle?) { 10 super.onCreate(savedInstanceState) 11 setContentView(R.layout.activity_main) 12 13 val pAdapter = PagerAdapter(this) 14 calendar_pager.adapter = pAdapter 15 calendar_pager.registerOnPageChangeCallback(object: ViewPager2.OnPageChangeCallback() { 16 private var jump_position = -1 17 override fun onPageSelected(position: Int) { 18 super.onPageSelected(position) 19 if (position == 0) { 20 jump_position = 3 21 pAdapter.overPrevious() 22 }else if (position == 4) { 23 jump_position = 1 24 pAdapter.overNext() 25 } 26 val itemId = PagerAdapter(this@MainActivity).getItemId(position) 27 Toast.makeText(applicationContext, itemId.toString(), Toast.LENGTH_LONG).show() 28 } 29 override fun onPageScrollStateChanged(state: Int) { 30 super.onPageScrollStateChanged(state) 31 if(state == ViewPager2.SCROLL_STATE_IDLE && jump_position >= 0) { 32 calendar_pager.setCurrentItem(jump_position ,false) 33 jump_position = -1 34 } 35 } 36 }) 37 calendar_pager.currentItem = 2 38 } 39} 40 41var overNext = 2 42var overPrevious = -2 43 44class PagerAdapter(fragment: FragmentActivity): FragmentStateAdapter(fragment) { 45 46 companion object { 47 val calendar = Calendar.getInstance() 48 val currentYear = calendar.get(Calendar.YEAR) 49 val currentMonth = calendar.get(Calendar.MONTH) + 1 50 val currentDay = calendar.get(Calendar.DATE) 51 } 52 53 //初期データ 54 val fmList = mutableListOf<Fragment>( 55 CalendarFragment(currentYear,currentMonth - 2,0), 56 CalendarFragment(currentYear,currentMonth - 1,0), 57 CalendarFragment(currentYear,currentMonth,currentDay), 58 CalendarFragment(currentYear,currentMonth + 1,0), 59 CalendarFragment(currentYear,currentMonth + 2,0) 60 ) 61 62 override fun createFragment(position: Int): Fragment { 63 return when(position) { 64 0 -> fmList[0] 65 1 -> fmList[1] 66 2 -> fmList[2] 67 3 -> fmList[3] 68 4 -> fmList[4] 69 else -> fmList[2] 70 } 71 } 72 73 override fun getItemId(position: Int): Long { 74 return super.getItemId(position) 75 } 76 77 override fun getItemCount() = 5 78 79 //初期データにする 80 fun initializeData() { 81 fmList.clear() 82 for (i in 0 until 5) { 83 fmList.add(CalendarFragment(currentYear,currentMonth - 2,0)) 84 fmList.add(CalendarFragment(currentYear,currentMonth - 1,0)) 85 fmList.add(CalendarFragment(currentYear,currentMonth,currentDay)) 86 fmList.add(CalendarFragment(currentYear,currentMonth + 1,0)) 87 fmList.add(CalendarFragment(currentYear,currentMonth + 2,0)) 88 } 89 } 90 91 //0にたどり着き、3に飛んだ時、後ろの三つのデータを削除する。そして前三つを補填する 92 fun overNext() { 93 for (index in 1..3) { 94 fmList.removeAt(fmList.size - 1) 95 } 96 for (index in 1..3) { 97 overNext += 1 98 println(currentMonth + overNext) 99 if(currentMonth + overNext > 12) { 100 fmList.add( 101 fmList.size - 1, 102 CalendarFragment(currentYear + 1, (currentMonth + overNext) - 12, 0) 103 ) 104 }else { 105 fmList.add( 106 fmList.size - 1, 107 CalendarFragment(currentYear, currentMonth + overNext, 0) 108 ) 109 } 110 } 111 } 112 113 //4にたどり着き、1に飛んだ時、前の三つのデータを削除する。そして、後ろ三つを補填する。 114 fun overPrevious() { 115 for (index in 1..3) { 116 fmList.removeAt(0) 117 } 118 for (index in 1..3) { 119 overPrevious -= 1 120 println(currentMonth + overPrevious) 121 if(currentMonth + overPrevious < 1) { 122 fmList.add(CalendarFragment(currentYear - 1, 12 - (currentMonth + overPrevious), 0)) 123 }else{ 124 fmList.add(CalendarFragment(currentYear, currentMonth + overPrevious, 0)) 125 } 126 } 127 128 } 129 130} 131
しかし、ページを延々とスクロールすることはできるのですが、3カ月以降と以前のカレンダーのデータが生成されず、どうしたものかと悩んでいます。
どのようにすれば、3カ月以降と以前のカレンダーを表示できるようになるでしょうか。
どなたかにアドバイスを頂けたら幸いです。
回答1件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。