Notice
Recent Posts
Recent Comments
Link
«   2025/05   »
1 2 3
4 5 6 7 8 9 10
11 12 13 14 15 16 17
18 19 20 21 22 23 24
25 26 27 28 29 30 31
Tags
more
Archives
Today
Total
관리 메뉴

끈기 있는 개발 공간

[Android] Jitpack으로 라이브러리 배포 - 3 본문

Android

[Android] Jitpack으로 라이브러리 배포 - 3

tenacy 2024. 8. 5. 20:28

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