(上一篇)http://www.reibang.com/p/2b9bdd5c2949介紹了怎么畫星期名。
這部介紹畫月的天數(shù)换况。
別爾蓋茨語錄
思路:
1.獲得今天的日期畦幢,畫對應的日期名字下。
2.計算出當前日期左邊右邊的值凫乖,并畫出
3.處理一些特殊情況鹿鳖,比如計算的天數(shù)不在當前月粱锐,兩位數(shù)和一位數(shù)的位置等
**4.按照距離關系,設定點擊事件钮呀。
實現(xiàn):
老規(guī)矩剑鞍,重寫View
的構造方法以及onMeasure
,onDraw
方法, 為了點擊事件重寫onTouch
方法.
1.定義需要的變量。
/**
* M paint
*/
private lateinit var mPaint: Paint
private lateinit var cPaint: Paint
/**
* Current 當前天
*/
private var current: Int? = null
/**
* Today 當前日期
*/
private var today: Int by Delegates.notNull()
/**
* Start 開始數(shù)字
*/
private var start: Int? = null
/**
* Month 當前月
*/
private var month: Int by Delegates.notNull()
/**
*本年
*/
private var year by Delegates.notNull<Int>()
/**
* Last month max 上月總天數(shù)
*/
private var lastMonthMax by Delegates.notNull<Int>()
/**
* Current month max 本月總天數(shù)
*/
private var currentMonthMax by Delegates.notNull<Int>()
/**
*負責點擊事件的處理爽醋。
**/
- 為了處理點擊事件蚁署,添加接口
/**
* Add on date click listener
* 點擊事件
* @constructor Create empty Add on date click listener
*/
interface AddOnDateClickListener {
fun singleClick(position: Int)
}
- 初始化變量。
private fun initView() {
//獲取今天的數(shù)據(jù)
val calendar = Calendar.getInstance()
//時區(qū)
calendar.timeZone = TimeZone.getTimeZone("GMT+8")
year = calendar.get(Calendar.YEAR)
//注:月從0開始的蚂四。
month = calendar.get(Calendar.MONTH) + 1
//今天
today = calendar.get(Calendar.DAY_OF_MONTH)
//周數(shù)
if (current == null) {
//注意:開始是從周日
current =if (calendar.get(Calendar.DAY_OF_WEEK)==7){
0
}else{
calendar.get(Calendar.DAY_OF_WEEK)-1
}
}
//比較周光戈,然后計算出開始日期.
if (start == null) {
start=today- current!! +1
}
//獲取上個月的天數(shù)。
//如果不再本年遂赠。
with(month - 1) {
lastMonthMax = if (this == 0) {
//12月的總數(shù)永遠是31天久妆,所以不需要從Calendar獲取。
31
} else {
getMonthLastDay(year, this)
}
}
//獲取本月最大天數(shù).
currentMonthMax = getMonthLastDay(year, month)
mPaint = Paint()
mPaint.textSize = DisplayUtils.dip2px(14F).toFloat()
mPaint.color = Color.parseColor("#3E3E3F")
mPaint.isAntiAlias = true
cPaint = Paint()
cPaint.color = Color.parseColor("#005BAB")
cPaint.isAntiAlias = true
}
- 重寫
onMeasure
方法跷睦,并且進行Padding
值的運算
//寫死寬度筷弦,高度最少37dp并且添加左右Padding值。
setMeasuredDimension(
widthMeasureSpec,
(DisplayUtils.dip2px(37F) + DisplayUtils.dip2Px(paddingBottom+paddingTop)).toInt()
)
5.重寫onDraw
方法
//index (索引) 0...6, value (值) -1...6(取決于當前的日期)
for ((index, value: Int) in (start!!..start!! + 6).withIndex()) {
mPaint.color = Color.parseColor("#3E3E3F")
//要畫的數(shù)字(天數(shù)抑诸,可能是上月的烂琴,也可能是下個月的。)
var tempPrintValue = value
//如果是當天蜕乡,畫圓形奸绷,畫天數(shù)文字。
if (current!! - 1 == index) {
//判斷
//如果低于本月层玲。
if (value <= 0) {
tempPrintValue = lastMonthMax + value
}
//如果超過本月
if (value > currentMonthMax) {
tempPrintValue = value - currentMonthMax
}
mPaint.color = Color.WHITE
//畫園健盒。
canvas?.drawCircle(
(index * width) / 7F + DisplayUtils.dip2px(
if (tempPrintValue > 9) {
31F
} else {
27F
}
),
((height/2).toFloat()),
DisplayUtils.dip2px(12F).toFloat(),
cPaint
)
//描繪天數(shù).
canvas?.drawText(
tempPrintValue.toString(),
(index * width) / 7F + DisplayUtils.dip2px(
if (index.toString().length > 1) {
18F
} else {
23F
}
),
(height/2)+DisplayUtils.dip2Px(5),mPaint
)
} else {
//判斷
//如果低于本月。
if (value <= 0) {
tempPrintValue = lastMonthMax + value
mPaint.color = Color.parseColor("#7E7E7E")
}
//如果超過本月
if (value > currentMonthMax) {
tempPrintValue = value - currentMonthMax
mPaint.color = Color.parseColor("#7E7E7E")
}
//描繪天數(shù).
canvas?.drawText(
tempPrintValue.toString(),
(index * width) / 7F + DisplayUtils.dip2px(
if (tempPrintValue.toString().length > 1) {
18F
} else {
23F
}
),
(height/2)+DisplayUtils.dip2Px(5),
// DisplayUtils.dip2px(24F).toFloat(),
mPaint
)
}
}
canvas?.save()
注:onDraw
里面處理了一位數(shù)和兩位數(shù)的時候的圓形的位置称簿。
6.點擊事件的處理。
主要思路:把寬度等7分惰帽,然后不同的區(qū)域給對應的值憨降。
更改當前選定的日期,并且重繪该酗,高亮授药。
/**
* 點擊事件的處理士嚎。
*/
override fun onTouchEvent(event: MotionEvent?): Boolean {
val x = event!!.x
//注意:只處理點(down),不處理up悔叽,move等莱衩,
if (event.action == MotionEvent.ACTION_DOWN) {
when (x.toInt()) {
in 0..width / 7 -> {
this.singleClick(1)
current = 1
}
in width * 1 / 7..width * 2 / 7 -> {
this.singleClick(2)
current = 2
}
in width * 2 / 7..width * 3 / 7 -> {
this.singleClick(3)
current = 3
}
in width * 3 / 7..width * 4 / 7 -> {
this.singleClick(4)
current = 4
}
in width * 4 / 7..width * 5 / 7 -> {
this.singleClick(5)
current = 5
}
in width * 5 / 7..width * 6 / 7 -> {
this.singleClick(6)
current = 6
}
in width * 6 / 7..width -> {
this.singleClick(7)
current = 7
}
}
//參數(shù)重新初始化。
initView()
//重繪
postInvalidate()
}
return true
}
- 使用的Utils娇澎。
/**
* 得到指定月的天數(shù)
*/
private fun getMonthLastDay(year: Int, month: Int): Int {
val a = Calendar.getInstance()
a[Calendar.YEAR] = year
a[Calendar.MONTH] = month - 1
a[Calendar.DATE] = 1 //把日期設置為當月第一天
a.roll(Calendar.DATE, -1) //日期回滾一天笨蚁,也就是最后一天
return a[Calendar.DATE]
}
/**
* dp轉(zhuǎn)px
*
* @param dipValue
* @return
*/
fun dip2px(dipValue: Float): Int {
val scale: Float = Resources.getSystem().displayMetrics.density
return (dipValue * scale + 0.5f).toInt()
}
/**
*點擊事件的處理。
**/
override fun singleClick(position: Int) {
Toast.makeText(context,"選中${start!!+position-1}", Toast.LENGTH_LONG).show()
}
最后跟上一篇的星期名結(jié)合趟庄。
Screenshot_20210920_035304.png
Screenshot_20210920_035309.png
完美括细,收工。