使用Calendar實現自定義日歷

為什么要自定義日歷?

在日常的工作中,很多時候的需求不是一個默認日歷能夠勝任的,雖然很多時候可以去GitHub上面搜索相關的庫,但是總是會有一些局限性,這個時候就想到了自己來寫一個日歷控件,這樣又方便還符合自己APP的主題,兩全其美。

廢話不多說,先上圖:


需要使用哪些工具?

1、ViewPager肯定是首要的,因為我們的日歷需要能夠左右滑動切換

2、最最重要的當然是Calendar啦,它能夠很好的幫助我們獲取需要的時間

介紹一下Calendar的幾個重要的方法

1、set方法:通過名字我們也知道這是一個賦值的方法,那么怎么使用呢?


val a = Calendar.getInstance()

//a.set(field:Int,value:Int) 參數一是我們需要賦值的類型 參數二是我們需要賦值的值

比方說我現在要把當前的日期設置為1號

a.set(Calendar.DATE,1) //這樣就把日期改為了1號

其他的類推就行。

通過設置我們可以獲得當月1號是星期幾

val week = a.get(Calendar.DAY_OF_WEEK)

這樣我們就知道從哪個位置開始啦


2、getActualMaximum:獲取給定日歷字段的可能最大值


我們需要獲取當前月最大天數,如果不用這個方法,我們需要去判斷當前月是大月還是小月,今年是閏年還是平年,有了這個方法就不需要啦

val a = Calendar.getInstance()

val days = a.getActualMaximum(Calendar.DATE)


3、add方法:添加


這個方法也是很實用的一個方法,比方說我們現在是1號我需要知道2號的時間戳,最笨的方法當然是拿之前的時間戳+24*3600,有了add方法就不需要了,我們只需要

a.add(Calendar.DATE, 1)

這樣就把時間戳往后加了一天,是不是很方便。

Calendar里面還有一個同類的方法roll

a.roll(Calendar.DATE,1)兩者都能往后一天

但是兩個是有區別的

比方說現在是2018年1月31號

a.add(Calendar.DATE, 1)得出的會是2018年2月1號

a.roll(Calendar.DATE,1)得出的會是2018年1月1號

也就是說add會影響整個時間戳,而roll只會影響當前這個量級


現在我們知道了1號需要的位置和總天數,那么數據源就有了


val mDatas = ArrayList()

for (i in 1 until getWeekOfFirstDayInMonth()) {

????????mDatas.add(DatePickerBean2(0, 0))

}

val b = Calendar.getInstance()

b.timeInMillis = timeMillis.toLong() * 1000

b.set(Calendar.DATE, 1)

for (i in 0 until getDaysOfMonth(timeMillis)) { ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? mDatas.add(DatePickerBean2((b.timeInMillis / 1000).toInt(), 0))

b.add(Calendar.DATE, 1)

}


一個簡單的日歷就有了,通過Calendar類,我們可以很方便的得到我們想要的數據



class DatePickerDialog2 : BaseActivity() {

private var timeMillis = 0

private var mViews = ArrayList()

private var pAdapter: MyAdapter? = null

private var isStart = 0

private var isEnd = 0

companion object {

const val REQUEST_CODE = 1718

fun show(context: Activity) {

val intent = Intent(context, DatePickerDialog2::class.java) context.startActivityForResult(intent, REQUEST_CODE)

}

}

?override fun bindlayout(): Int = R.layout.fragment_date_picker2

override fun initListener() {

tvPre.setOnClickListener {

if (mPager.currentItem > 0) {

mPager.setCurrentItem(mPager.currentItem - 1, true)

}

}

tvNext.setOnClickListener {

mPager.setCurrentItem(mPager.currentItem + 1, true)

}

tvCancel.setOnClickListener { finish() }

tvConfirm.setOnClickListener {

if (isStart == 0) {

toast("請選擇開始日期") return@setOnClickListener

}

if (isEnd == 0) {

toast("請選擇結束日期")

return@setOnClickListener

}

val intent = Intent()

intent.putExtra("start", isStart)

intent.putExtra("end", isEnd)

setResult(Activity.RESULT_OK, intent)

finish()

}

}

override fun init() {

timeMillis = (Calendar.getInstance().timeInMillis / 1000).toInt() tvDate.bindText(TimeUtils.formatDate("yyyy年MM月", timeMillis.toString())) initAdapter()

mPager.addOnPageChangeListener(object :ViewPager.SimpleOnPageChangeListener() {

override fun onPageSelected(position: Int) { tvDate.bindText(TimeUtils.formatDate("yyyy年MM月",mViews[position].timeMillis.toString()))

if (position == mViews.size - 1) {

val a = Calendar.getInstance()

a.timeInMillis = timeMillis.toLong() * 1000

a.add(Calendar.MONTH, 1)

timeMillis = (a.timeInMillis / 1000).toInt()

initAdapter()

}

}

}) }

private fun initAdapter() {

val mDatas = ArrayList()

for (i in 1 until getWeekOfFirstDayInMonth()) {

mDatas.add(DatePickerBean2(0, 0))

}

val b = Calendar.getInstance()

b.timeInMillis = timeMillis.toLong() * 1000

b.set(Calendar.DATE, 1)

for (i in 0 until getDaysOfMonth(timeMillis)) { mDatas.add(DatePickerBean2((b.timeInMillis / 1000).toInt(), 0))

b.add(Calendar.DATE, 1)

}

val aadapter = DatePickerAdapter2(this@DatePickerDialog2, mDatas)

val contents = RecyclerView(this@DatePickerDialog2)

contents.layoutParams = ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT)

contents.apply {

layoutManager = GridLayoutManager(this@DatePickerDialog2, 7) setHasFixedSize(true)

adapter = aadapter

}

aadapter.setOnItemClickListener {

when (mDatas[it].selectType) {

0 ->

{

if (isStart == 0) {

if (isEnd == 0 || mDatas[it].timeMillis < isEnd) {

mDatas[it].selectType = 1 isStart = mDatas[it].timeMillis

} else {

toast("開始日期不能在結束日期之后哦")

}

} else if (isEnd == 0) {

if (isStart == 0 || isStart < mDatas[it].timeMillis) {

mDatas[it].selectType = 2

isEnd = mDatas[it].timeMillis

} else {

toast("結束日期不能在開始日期之前哦")

}

}

}

1 -> {

mDatas[it].selectType = 0

isStart = 0

}

2 -> {

mDatas[it].selectType = 0

isEnd = 0

}

}

aadapter.refresh(mDatas).notifyItemChanged(it)

}

if (pAdapter == null) {

pAdapter = MyAdapter()

mViews.add(MyView(contents, timeMillis))

mPager.adapter = pAdapter

if (mPager.currentItem == mViews.size - 1) {

val a = Calendar.getInstance()

a.timeInMillis = timeMillis.toLong() * 1000

a.add(Calendar.MONTH, 1)

timeMillis = (a.timeInMillis / 1000).toInt()

initAdapter()

}

} else {

mViews.add(MyView(contents, timeMillis))

mPager.adapter.notifyDataSetChanged()

}

}

private inner class MyAdapter : PagerAdapter() {

override fun isViewFromObject(view: View?, obj: Any?): Boolean = view == obj

override fun getCount(): Int = mViews.size

override fun instantiateItem(container: ViewGroup, position: Int): Any { container.addView(mViews[position].view)

return mViews[position].view }

override fun destroyItem(container: ViewGroup, position: Int, `object`: Any?) { container.removeView(mViews[position].view)

}

}

private fun getWeekOfFirstDayInMonth(): Int {

val a = Calendar.getInstance()

a.timeInMillis = timeMillis.toLong() * 1000

a.set(Calendar.DATE, 1)

return a.get(Calendar.DAY_OF_WEEK)

}

data class MyView(val view: View, val timeMillis: Int)

private fun getDaysOfMonth(timeMillis: Int): Int {

val a = Calendar.getInstance()

a.timeInMillis = timeMillis.toLong() * 1000

return a.getActualMaximum(Calendar.DATE)

}

}

?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容

  • 最近項目中用到自定義日歷組件,找來找去,最后發現GitHub的material-calendarview這個項目最...
    colin2017閱讀 1,556評論 0 0
  • ¥開啟¥ 【iAPP實現進入界面執行逐一顯】 〖2017-08-25 15:22:14〗 《//首先開一個線程,因...
    小菜c閱讀 6,497評論 0 17
  • 背景 一年多以前我在知乎上答了有關LeetCode的問題, 分享了一些自己做題目的經驗。 張土汪:刷leetcod...
    土汪閱讀 12,766評論 0 33
  • 大多數人因為沒有長遠的規劃,他們也搞不清楚自己究竟真正要的是什么?所以無法發現自己身邊隱藏著可以改變他一生的貴人和...
    希虹閱讀 382評論 0 0
  • 可能他不是你心目中理想的白馬王子,但是你可以做好他的公主。
    攸寧er閱讀 169評論 0 2