끈기 있는 개발 공간
[Android] Jitpack으로 라이브러리 배포 - 3 본문
https://github.com/tentenacy/DragHandleBottomSheet
라이브러리 추상화
[Android] Jitpack으로 라이브러리 배포 - 1에서 만든 DragHandleBottomSheet은HandleDraggableBottomSheetDialogFragment
이라는 abstract class로 구현되었다.
하지만 이는 꼭 필요한 경우가 아니면 abstract class로 라이브러리화 할 필요가 없다는 게 내 생각이다.
abstract class는 사용자에게 구현을 강제하기 때문에 사용자가 유연하게 라이브러리를 사용할 수 없다.
그래서 나는 kotiln의 DragHandleBottomSheet을 extension function으로 구현했다.
소스코드(Kotlin)
package com.tenutz.draghandlebs
import android.animation.ObjectAnimator
import android.annotation.SuppressLint
import android.view.MotionEvent
import android.view.View
import android.view.animation.DecelerateInterpolator
import com.google.android.material.bottomsheet.BottomSheetBehavior
import com.google.android.material.bottomsheet.BottomSheetDialogFragment
fun BottomSheetDialogFragment.makeDraggableByHandle(dragHandle: View, scrollVerticalRatio: Float = 0.45f, animatorDuration: Long = 300L, interpolatorFactor: Float = 2f) {
val rootView = this@makeDraggableByHandle.requireView()
val bottomSheet = dialog?.findViewById<View>(com.google.android.material.R.id.design_bottom_sheet)!!
val bottomSheetBehavior = BottomSheetBehavior.from(bottomSheet)
bottomSheetBehavior.isDraggable = false
dragHandle.setOnTouchListener(object : View.OnTouchListener {
private var lastTouchY = 0f
@SuppressLint("ClickableViewAccessibility")
override fun onTouch(v: View, event: MotionEvent): Boolean = when (event.action) {
MotionEvent.ACTION_DOWN -> {
updateTouchPosition(event)
true
}
MotionEvent.ACTION_MOVE -> {
drag(event)
updateTouchPosition(event)
true
}
MotionEvent.ACTION_UP -> {
if (isOutOfBoundary()) {
toStateExpanded()
} else {
toStateHidden()
}
true
}
else -> false
}
private fun updateTouchPosition(event: MotionEvent) {
lastTouchY = event.rawY
}
private fun drag(event: MotionEvent) {
val deltaY = event.rawY - lastTouchY
val maxY = rootView.height.toFloat() + bottomSheet.top.toFloat()
val minY = bottomSheet.top.toFloat()
if (bottomSheet.y + deltaY in minY..maxY) {
bottomSheet.y += deltaY
}
}
private fun isOutOfBoundary() = bottomSheet.y < rootView.height.toFloat() * (1 - scrollVerticalRatio) + bottomSheet.top
private fun toStateHidden() {
bottomSheetBehavior.state = BottomSheetBehavior.STATE_HIDDEN
}
private fun toStateExpanded() {
ObjectAnimator.ofFloat(bottomSheet, "translationY", 0f).apply {
interpolator = DecelerateInterpolator(interpolatorFactor)
duration = animatorDuration
start()
}
}
})
}
라이브러리 프로젝트 구조
예제를 볼 수 있는 Example 모듈이 하나 있고, 라이브러리를 제공하는 Lib 모듈이 하나 있다.
라이브러리 배포
라이브러리 배포 과정은 [Android] Jitpack으로 라이브러리 배포 - 2와 동일하다.
README.md 작성
README.md도 라이브러리 배포 못지 않게 중요하다. 라이브러리를 처음 접하는 사용자에게 길잡이가 되어 주기 때문이다.
여러 repository를 참고하여 작성했다. 평소에 잘 알지 못했던 라이센스도 알아보게 됐던 좋은 경험이었다.
어떻게 작성하는지 궁금하면 DragHandleBottomSheet repository의 README.md를 참고하면 도움이 될 것이다.
'Android' 카테고리의 다른 글
[Android] Jitpack으로 라이브러리 배포 - 2 (0) | 2024.08.05 |
---|---|
[Android] Jitpack으로 라이브러리 배포 - 1 (0) | 2024.08.05 |
데이터 바인딩 (1) | 2021.05.07 |
Comments