使用Calendar实现自定义日历

为什么要自定义日历?

在日常的工作中,很多时候的需求不是一个默认日历能够胜任的,虽然很多时候可以去GitHub上面搜索相关的库,但是总是会有一些局限性,这个时候就想到了自己来写一个日历控件,这样又方便还符合自己APP的主题,两全其美。

废话不多说,先上图:


使用Calendar实现自定义日历_第1张图片
使用Calendar实现自定义日历_第2张图片

需要使用哪些工具?

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)

}

}

你可能感兴趣的:(使用Calendar实现自定义日历)