-
Notifications
You must be signed in to change notification settings - Fork 0
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[feature/calendar2] 커스텀뷰 캘린더 #7
base: develop
Are you sure you want to change the base?
Changes from all commits
d7a2254
0f90dc1
a207ee3
0460e15
b8196fa
537e18f
0a93ca8
66a42f1
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
This file was deleted.
Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
@@ -0,0 +1,68 @@ | ||||||||||||||||||||||||||||||||||||
package com.teamcatchme.calendar_customview | ||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||
import android.content.Context | ||||||||||||||||||||||||||||||||||||
import android.graphics.* | ||||||||||||||||||||||||||||||||||||
import android.util.AttributeSet | ||||||||||||||||||||||||||||||||||||
import android.util.Log | ||||||||||||||||||||||||||||||||||||
import android.view.View | ||||||||||||||||||||||||||||||||||||
import androidx.core.content.res.ResourcesCompat | ||||||||||||||||||||||||||||||||||||
import com.teamcatchme.catchmesample.R | ||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||
class CalendarItemView @JvmOverloads | ||||||||||||||||||||||||||||||||||||
constructor( | ||||||||||||||||||||||||||||||||||||
context: Context, | ||||||||||||||||||||||||||||||||||||
attrs: AttributeSet? = null, | ||||||||||||||||||||||||||||||||||||
defStyleAttr: Int = 0, | ||||||||||||||||||||||||||||||||||||
private val date: Int? = null, | ||||||||||||||||||||||||||||||||||||
private val catchuList: Array<Int> = arrayOf(), | ||||||||||||||||||||||||||||||||||||
private val isPrevious: Boolean = false | ||||||||||||||||||||||||||||||||||||
) : | ||||||||||||||||||||||||||||||||||||
Comment on lines
+11
to
+19
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
우선 생성자 형식은 저런데 뷰의 생성자에 저런 인자들이 들어가도 되나 나도 자세히 몰라서 확인해봐야할 듯 There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 오키 일단 해보고 우리 리얼 레포에 PR날리기 전까지 나도 확인해보겠음!! |
||||||||||||||||||||||||||||||||||||
View(context, attrs, defStyleAttr) { | ||||||||||||||||||||||||||||||||||||
private var paint: Paint = Paint() | ||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||
private fun drawDateRect(canvas: Canvas, date: Int) { | ||||||||||||||||||||||||||||||||||||
paint.textSize = 36f | ||||||||||||||||||||||||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 실제에서는 이건 dp로 맞춰줘야할 것 같습니다. |
||||||||||||||||||||||||||||||||||||
if (isPrevious) paint.color = Color.GRAY | ||||||||||||||||||||||||||||||||||||
canvas.drawText( | ||||||||||||||||||||||||||||||||||||
date.toString(), | ||||||||||||||||||||||||||||||||||||
(width / 2).toFloat(), | ||||||||||||||||||||||||||||||||||||
((height / 2) - ((paint.descent() + paint.ascent()) / 2)), | ||||||||||||||||||||||||||||||||||||
paint | ||||||||||||||||||||||||||||||||||||
) | ||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||
private fun drawDateWithCatchuRect(canvas: Canvas, date: Int, catchuList: Array<Int>) { | ||||||||||||||||||||||||||||||||||||
paint.textSize = 30f | ||||||||||||||||||||||||||||||||||||
paint.color = Color.GRAY | ||||||||||||||||||||||||||||||||||||
val contextResources = context.resources | ||||||||||||||||||||||||||||||||||||
val catchuDrawable = | ||||||||||||||||||||||||||||||||||||
ResourcesCompat.getDrawable(contextResources, R.drawable.ic_cachu1, null); | ||||||||||||||||||||||||||||||||||||
runCatching { | ||||||||||||||||||||||||||||||||||||
val catchuBitmap = catchuDrawable?.toBitmap() | ||||||||||||||||||||||||||||||||||||
canvas.drawBitmap( | ||||||||||||||||||||||||||||||||||||
requireNotNull(catchuBitmap), | ||||||||||||||||||||||||||||||||||||
(width / 2 - catchuBitmap.width / 2).toFloat(), | ||||||||||||||||||||||||||||||||||||
0f, | ||||||||||||||||||||||||||||||||||||
null | ||||||||||||||||||||||||||||||||||||
) | ||||||||||||||||||||||||||||||||||||
canvas.drawText( | ||||||||||||||||||||||||||||||||||||
date.toString(), | ||||||||||||||||||||||||||||||||||||
(width / 2).toFloat(), | ||||||||||||||||||||||||||||||||||||
(catchuBitmap.height + 28).toFloat(), | ||||||||||||||||||||||||||||||||||||
paint | ||||||||||||||||||||||||||||||||||||
) | ||||||||||||||||||||||||||||||||||||
}.onFailure { Log.e("error", it.toString()) } | ||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||
// 누르면 프라그먼트 뿅 하게 리스너 추가하기 | ||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||
override fun onDraw(canvas: Canvas?) { | ||||||||||||||||||||||||||||||||||||
super.onDraw(canvas) | ||||||||||||||||||||||||||||||||||||
paint.textAlign = Paint.Align.CENTER | ||||||||||||||||||||||||||||||||||||
if (canvas == null) return; | ||||||||||||||||||||||||||||||||||||
date?.run { | ||||||||||||||||||||||||||||||||||||
if (catchuList.isNotEmpty()) drawDateWithCatchuRect(canvas, this, catchuList) | ||||||||||||||||||||||||||||||||||||
else drawDateRect(canvas, this) | ||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,55 @@ | ||
package com.teamcatchme.calendar_customview | ||
|
||
import android.content.Context | ||
import android.util.AttributeSet | ||
import android.util.Log | ||
import android.view.ViewGroup | ||
import android.widget.LinearLayout | ||
import androidx.core.view.children | ||
import java.util.* | ||
|
||
class CalendarView @JvmOverloads | ||
constructor( | ||
context: Context, | ||
attrs: AttributeSet? = null, | ||
defStyleAttr: Int = 0 | ||
) : ViewGroup(context, attrs, defStyleAttr) { | ||
fun drawCalendar(dateObject: Date) { | ||
val dateCalendar = Calendar.getInstance() | ||
dateCalendar.time = dateObject | ||
dateCalendar.set(Calendar.DATE, 1) | ||
val year = dateCalendar.get(Calendar.YEAR) | ||
val month = dateCalendar.get(Calendar.MONTH) + 1 | ||
val firstDayOfMonth = dateCalendar.get(Calendar.DAY_OF_WEEK) - 1 | ||
val lastDateOfMonth = dateCalendar.getActualMaximum(Calendar.DATE) | ||
Comment on lines
+23
to
+24
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 변수명 굳 |
||
dateCalendar.set(Calendar.MONTH, month - 2) | ||
val lastDateOfLastMonth = dateCalendar.getActualMaximum(Calendar.DATE) | ||
if (firstDayOfMonth != 6) { | ||
((lastDateOfLastMonth - firstDayOfMonth)..lastDateOfLastMonth).forEach { blank -> | ||
addView(CalendarItemView(context = context, date = blank, isPrevious = true)) | ||
} | ||
} | ||
(1..lastDateOfMonth).forEach { date -> | ||
if (date % 2 == 0) addView( | ||
CalendarItemView( | ||
context = context, | ||
date = date, | ||
catchuList = arrayOf(1, 2, 3) | ||
) | ||
) | ||
else addView(CalendarItemView(context = context, date = date)) | ||
} | ||
} | ||
|
||
override fun onLayout(p0: Boolean, p1: Int, p2: Int, p3: Int, p4: Int) { | ||
val iWidth = (width / 7).toFloat() | ||
val iHeight = (width / 7).toFloat() | ||
var index = 0 | ||
children.forEach { view -> | ||
val left = (index % 7) * iWidth | ||
val top = (index / 7) * iHeight | ||
view.layout(left.toInt(), top.toInt(), (left + iWidth).toInt(), (top + iHeight).toInt()) | ||
index++ | ||
} | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
package com.teamcatchme.calendar_customview | ||
|
||
import androidx.appcompat.app.AppCompatActivity | ||
import android.os.Bundle | ||
import com.teamcatchme.catchmesample.R | ||
import com.teamcatchme.catchmesample.databinding.ActivityCustomCalendarBinding | ||
|
||
class CustomCalendarActivity : AppCompatActivity() { | ||
lateinit var binding: ActivityCustomCalendarBinding | ||
override fun onCreate(savedInstanceState: Bundle?) { | ||
super.onCreate(savedInstanceState) | ||
binding = ActivityCustomCalendarBinding.inflate(layoutInflater) | ||
setContentView(binding.root) | ||
initCalendar() | ||
} | ||
|
||
private fun initCalendar() { | ||
val calendarAdapter = CustomCalendarAdapter(this) | ||
binding.viewpagerCustomCalendar.apply { | ||
adapter = calendarAdapter | ||
setCurrentItem(CustomCalendarAdapter.START_POSITION, true) | ||
} | ||
|
||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
package com.teamcatchme.calendar_customview | ||
|
||
import androidx.fragment.app.Fragment | ||
import androidx.fragment.app.FragmentActivity | ||
import androidx.viewpager2.adapter.FragmentStateAdapter | ||
import java.util.* | ||
|
||
class CustomCalendarAdapter(fragmentActivity: FragmentActivity) : | ||
FragmentStateAdapter(fragmentActivity) { | ||
|
||
private var startTime: Calendar = Calendar.getInstance() | ||
|
||
override fun getItemCount(): Int = Int.MAX_VALUE | ||
|
||
override fun createFragment(position: Int): Fragment { | ||
val millsId = getItemId(position) | ||
return CustomCalendarFragment.newInstance(millsId) | ||
} | ||
|
||
override fun getItemId(position: Int): Long { | ||
val start = startTime.clone() as Calendar | ||
start.add(Calendar.MONTH, position - START_POSITION) | ||
return start.timeInMillis | ||
} | ||
|
||
companion object { | ||
const val START_POSITION = Int.MAX_VALUE / 2 | ||
} | ||
|
||
|
||
} |
Original file line number | Diff line number | Diff line change | ||||||||
---|---|---|---|---|---|---|---|---|---|---|
@@ -0,0 +1,56 @@ | ||||||||||
package com.teamcatchme.calendar_customview | ||||||||||
|
||||||||||
import android.os.Bundle | ||||||||||
import android.view.LayoutInflater | ||||||||||
import android.view.View | ||||||||||
import android.view.ViewGroup | ||||||||||
import androidx.fragment.app.Fragment | ||||||||||
import com.teamcatchme.catchmesample.databinding.FragmentCustomCalendarBinding | ||||||||||
import java.util.* | ||||||||||
import kotlin.properties.Delegates | ||||||||||
|
||||||||||
class CustomCalendarFragment : Fragment() { | ||||||||||
|
||||||||||
companion object { | ||||||||||
private var MILLS_ID: String = "MILLS_ID" | ||||||||||
private var millsId: Long = 0L | ||||||||||
|
||||||||||
fun newInstance(millsId: Long): CustomCalendarFragment { | ||||||||||
val fragment = CustomCalendarFragment() | ||||||||||
val args = Bundle() | ||||||||||
args.putLong(MILLS_ID, millsId) | ||||||||||
fragment.arguments = args | ||||||||||
Comment on lines
+20
to
+22
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
3줄을 1줄로 |
||||||||||
|
||||||||||
return fragment | ||||||||||
} | ||||||||||
} | ||||||||||
|
||||||||||
private var _binding: FragmentCustomCalendarBinding? = null | ||||||||||
private val binding: FragmentCustomCalendarBinding | ||||||||||
get() = requireNotNull(_binding) | ||||||||||
|
||||||||||
override fun onCreateView( | ||||||||||
inflater: LayoutInflater, | ||||||||||
container: ViewGroup?, | ||||||||||
savedInstanceState: Bundle? | ||||||||||
): View { | ||||||||||
_binding = FragmentCustomCalendarBinding.inflate(inflater, container, false) | ||||||||||
arguments?.let { | ||||||||||
millsId = it.getLong(MILLS_ID) | ||||||||||
} | ||||||||||
Comment on lines
+38
to
+40
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 👍🏻 |
||||||||||
initView() | ||||||||||
return binding.root | ||||||||||
} | ||||||||||
|
||||||||||
private fun initView() { | ||||||||||
val date = Date(millsId) | ||||||||||
binding.text.text = date.toString() | ||||||||||
binding.calendarView.drawCalendar(date) | ||||||||||
} | ||||||||||
|
||||||||||
override fun onDestroyView() { | ||||||||||
super.onDestroyView() | ||||||||||
_binding = null | ||||||||||
} | ||||||||||
|
||||||||||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
package com.teamcatchme.calendar_customview | ||
|
||
import android.graphics.Bitmap | ||
import android.graphics.Canvas | ||
import android.graphics.drawable.BitmapDrawable | ||
import android.graphics.drawable.Drawable | ||
|
||
|
||
fun Drawable.toBitmap(): Bitmap? { | ||
if (this is BitmapDrawable) { | ||
return this.bitmap | ||
} | ||
val bitmap = | ||
Bitmap.createBitmap( | ||
this.intrinsicWidth, | ||
this.intrinsicHeight, | ||
Bitmap.Config.ARGB_8888 | ||
) | ||
val canvas = Canvas(bitmap) | ||
this.setBounds(0, 0, canvas.getWidth(), canvas.getHeight()) | ||
this.draw(canvas) | ||
return bitmap | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
<?xml version="1.0" encoding="utf-8"?> | ||
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" | ||
xmlns:app="http://schemas.android.com/apk/res-auto" | ||
xmlns:tools="http://schemas.android.com/tools" | ||
android:layout_width="match_parent" | ||
android:layout_height="match_parent" | ||
tools:context="com.teamcatchme.calendar_customview.CustomCalendarActivity"> | ||
|
||
<androidx.viewpager2.widget.ViewPager2 | ||
android:id="@+id/viewpager_custom_calendar" | ||
android:layout_width="match_parent" | ||
android:layout_height="match_parent" /> | ||
|
||
</androidx.constraintlayout.widget.ConstraintLayout> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
이거 벌써 rc 나왔구나 코루틴 사용하기 더 편해지겠누