使用Calendar實(shí)現(xiàn)自定義日歷

為什么要自定義日歷?

在日常的工作中濒生,很多時(shí)候的需求不是一個(gè)默認(rèn)日歷能夠勝任的佩耳,雖然很多時(shí)候可以去GitHub上面搜索相關(guān)的庫,但是總是會(huì)有一些局限性真椿,這個(gè)時(shí)候就想到了自己來寫一個(gè)日歷控件鹃答,這樣又方便還符合自己APP的主題,兩全其美突硝。

廢話不多說测摔,先上圖:


需要使用哪些工具?

1解恰、ViewPager肯定是首要的锋八,因?yàn)槲覀兊娜諝v需要能夠左右滑動(dòng)切換

2、最最重要的當(dāng)然是Calendar啦护盈,它能夠很好的幫助我們獲取需要的時(shí)間

介紹一下Calendar的幾個(gè)重要的方法

1挟纱、set方法:通過名字我們也知道這是一個(gè)賦值的方法,那么怎么使用呢腐宋?


val a = Calendar.getInstance()

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

比方說我現(xiàn)在要把當(dāng)前的日期設(shè)置為1號(hào)

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

其他的類推就行紊服。

通過設(shè)置我們可以獲得當(dāng)月1號(hào)是星期幾

val week = a.get(Calendar.DAY_OF_WEEK)

這樣我們就知道從哪個(gè)位置開始啦


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


我們需要獲取當(dāng)前月最大天數(shù),如果不用這個(gè)方法欺嗤,我們需要去判斷當(dāng)前月是大月還是小月参萄,今年是閏年還是平年,有了這個(gè)方法就不需要啦

val a = Calendar.getInstance()

val days = a.getActualMaximum(Calendar.DATE)


3煎饼、add方法:添加


這個(gè)方法也是很實(shí)用的一個(gè)方法讹挎,比方說我們現(xiàn)在是1號(hào)我需要知道2號(hào)的時(shí)間戳,最笨的方法當(dāng)然是拿之前的時(shí)間戳+24*3600吆玖,有了add方法就不需要了筒溃,我們只需要

a.add(Calendar.DATE, 1)

這樣就把時(shí)間戳往后加了一天,是不是很方便衰伯。

Calendar里面還有一個(gè)同類的方法roll

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

但是兩個(gè)是有區(qū)別的

比方說現(xiàn)在是2018年1月31號(hào)

a.add(Calendar.DATE, 1)得出的會(huì)是2018年2月1號(hào)

a.roll(Calendar.DATE,1)得出的會(huì)是2018年1月1號(hào)

也就是說add會(huì)影響整個(gè)時(shí)間戳铡羡,而roll只會(huì)影響當(dāng)前這個(gè)量級(jí)


現(xiàn)在我們知道了1號(hào)需要的位置和總天數(shù)积蔚,那么數(shù)據(jù)源就有了


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)

}


一個(gè)簡單的日歷就有了意鲸,通過Calendar類,我們可以很方便的得到我們想要的數(shù)據(jù)



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("請(qǐng)選擇開始日期") return@setOnClickListener

}

if (isEnd == 0) {

toast("請(qǐng)選擇結(jié)束日期")

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("開始日期不能在結(jié)束日期之后哦")

}

} else if (isEnd == 0) {

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

mDatas[it].selectType = 2

isEnd = mDatas[it].timeMillis

} else {

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

}

}

}

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)

}

}

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末尽爆,一起剝皮案震驚了整個(gè)濱河市怎顾,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌漱贱,老刑警劉巖槐雾,帶你破解...
    沈念sama閱讀 222,464評(píng)論 6 517
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異幅狮,居然都是意外死亡募强,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 95,033評(píng)論 3 399
  • 文/潘曉璐 我一進(jìn)店門崇摄,熙熙樓的掌柜王于貴愁眉苦臉地迎上來擎值,“玉大人,你說我怎么就攤上這事逐抑○” “怎么了?”我有些...
    開封第一講書人閱讀 169,078評(píng)論 0 362
  • 文/不壞的土叔 我叫張陵厕氨,是天一觀的道長进每。 經(jīng)常有香客問我,道長命斧,這世上最難降的妖魔是什么田晚? 我笑而不...
    開封第一講書人閱讀 59,979評(píng)論 1 299
  • 正文 為了忘掉前任,我火速辦了婚禮国葬,結(jié)果婚禮上贤徒,老公的妹妹穿的比我還像新娘遭京。我一直安慰自己,他們只是感情好泞莉,可當(dāng)我...
    茶點(diǎn)故事閱讀 69,001評(píng)論 6 398
  • 文/花漫 我一把揭開白布哪雕。 她就那樣靜靜地躺著,像睡著了一般鲫趁。 火紅的嫁衣襯著肌膚如雪斯嚎。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 52,584評(píng)論 1 312
  • 那天挨厚,我揣著相機(jī)與錄音堡僻,去河邊找鬼。 笑死疫剃,一個(gè)胖子當(dāng)著我的面吹牛钉疫,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播巢价,決...
    沈念sama閱讀 41,085評(píng)論 3 422
  • 文/蒼蘭香墨 我猛地睜開眼牲阁,長吁一口氣:“原來是場噩夢(mèng)啊……” “哼!你這毒婦竟也來了壤躲?” 一聲冷哼從身側(cè)響起城菊,我...
    開封第一講書人閱讀 40,023評(píng)論 0 277
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎碉克,沒想到半個(gè)月后凌唬,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 46,555評(píng)論 1 319
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡漏麦,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,626評(píng)論 3 342
  • 正文 我和宋清朗相戀三年客税,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片撕贞。...
    茶點(diǎn)故事閱讀 40,769評(píng)論 1 353
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡更耻,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出麻掸,到底是詐尸還是另有隱情酥夭,我是刑警寧澤,帶...
    沈念sama閱讀 36,439評(píng)論 5 351
  • 正文 年R本政府宣布脊奋,位于F島的核電站熬北,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏诚隙。R本人自食惡果不足惜讶隐,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 42,115評(píng)論 3 335
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望久又。 院中可真熱鬧巫延,春花似錦效五、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,601評(píng)論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至疼阔,卻和暖如春戒劫,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背婆廊。 一陣腳步聲響...
    開封第一講書人閱讀 33,702評(píng)論 1 274
  • 我被黑心中介騙來泰國打工迅细, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人淘邻。 一個(gè)月前我還...
    沈念sama閱讀 49,191評(píng)論 3 378
  • 正文 我出身青樓茵典,卻偏偏與公主長得像,于是被迫代替她去往敵國和親宾舅。 傳聞我的和親對(duì)象是個(gè)殘疾皇子统阿,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,781評(píng)論 2 361

推薦閱讀更多精彩內(nèi)容

  • 最近項(xiàng)目中用到自定義日歷組件,找來找去贴浙,最后發(fā)現(xiàn)GitHub的material-calendarview這個(gè)項(xiàng)目最...
    colin2017閱讀 1,528評(píng)論 0 0
  • ¥開啟¥ 【iAPP實(shí)現(xiàn)進(jìn)入界面執(zhí)行逐一顯】 〖2017-08-25 15:22:14〗 《//首先開一個(gè)線程砂吞,因...
    小菜c閱讀 6,449評(píng)論 0 17
  • 背景 一年多以前我在知乎上答了有關(guān)LeetCode的問題, 分享了一些自己做題目的經(jīng)驗(yàn)。 張土汪:刷leetcod...
    土汪閱讀 12,748評(píng)論 0 33
  • 大多數(shù)人因?yàn)闆]有長遠(yuǎn)的規(guī)劃崎溃,他們也搞不清楚自己究竟真正要的是什么?所以無法發(fā)現(xiàn)自己身邊隱藏著可以改變他一生的貴人和...
    希虹閱讀 374評(píng)論 0 0
  • 可能他不是你心目中理想的白馬王子盯质,但是你可以做好他的公主袁串。
    攸寧er閱讀 167評(píng)論 0 2