728x90
반응형
코틀린 코드
import com.google.android.material.bottomnavigation.BottomNavigationView
import android.content.Context
import android.util.AttributeSet
import androidx.core.content.ContextCompat
import android.graphics.*
class CustomBottomNavigationView : BottomNavigationView {
private var mPath: Path = Path()
private var mPaint: Paint = Paint()
private val CURVE_CIRCLE_RADIUS = 190 / 2
private val mFirstCurveStartPoint = Point()
private val mFirstCurveEndPoint = Point()
private val mFirstCurveControlPoint1 = Point()
private val mFirstCurveControlPoint2 = Point()
private var mSecondCurveStartPoint = Point()
private val mSecondCurveEndPoint = Point()
private val mSecondCurveControlPoint1 = Point()
private val mSecondCurveControlPoint2 = Point()
private var mNavigationBarWidth: Int = 0
private var mNavigationBarHeight: Int = 0
constructor(context: Context, attrs: AttributeSet, defStyleAttr: Int) : super(context, attrs, defStyleAttr) {
init()
}
constructor(context: Context, attrs: AttributeSet) : super(context, attrs) {
init()
}
constructor(context: Context) : super(context) {
init()
}
private fun init() {
mPaint.style = Paint.Style.FILL_AND_STROKE
mPaint.color = ContextCompat.getColor(context, R.color.white)
setBackgroundColor(Color.TRANSPARENT)
}
override fun onLayout(changed: Boolean, left: Int, top: Int, right: Int, bottom: Int) {
super.onLayout(changed, left, top, right, bottom)
}
override fun onSizeChanged(w: Int, h: Int, oldw: Int, oldh: Int) {
super.onSizeChanged(w, h, oldw, oldh)
mNavigationBarWidth = width
mNavigationBarHeight = height
mFirstCurveStartPoint.set(mNavigationBarWidth / 2 - CURVE_CIRCLE_RADIUS * 2 - CURVE_CIRCLE_RADIUS / 3, 0)
mFirstCurveEndPoint.set(mNavigationBarWidth / 2, CURVE_CIRCLE_RADIUS + CURVE_CIRCLE_RADIUS / 4)
mSecondCurveStartPoint = mFirstCurveEndPoint
mSecondCurveEndPoint.set(mNavigationBarWidth / 2 + CURVE_CIRCLE_RADIUS * 2 + CURVE_CIRCLE_RADIUS / 3, 0)
mFirstCurveControlPoint1.set(
mFirstCurveStartPoint.x + CURVE_CIRCLE_RADIUS + CURVE_CIRCLE_RADIUS / 4,
mFirstCurveStartPoint.y
)
mFirstCurveControlPoint2.set(
mFirstCurveEndPoint.x - CURVE_CIRCLE_RADIUS * 2 + CURVE_CIRCLE_RADIUS,
mFirstCurveEndPoint.y
)
mSecondCurveControlPoint1.set(
mSecondCurveStartPoint.x + CURVE_CIRCLE_RADIUS * 2 - CURVE_CIRCLE_RADIUS,
mSecondCurveStartPoint.y
)
mSecondCurveControlPoint2.set(
mSecondCurveEndPoint.x - (CURVE_CIRCLE_RADIUS + CURVE_CIRCLE_RADIUS / 4),
mSecondCurveEndPoint.y
)
mPath.reset()
mPath.moveTo(0F, 0F)
mPath.lineTo(mFirstCurveStartPoint.x.toFloat(), mFirstCurveStartPoint.y.toFloat())
mPath.cubicTo(
mFirstCurveControlPoint1.x.toFloat(), mFirstCurveControlPoint1.y.toFloat(),
mFirstCurveControlPoint2.x.toFloat(), mFirstCurveControlPoint2.y.toFloat(),
mFirstCurveEndPoint.x.toFloat(), mFirstCurveEndPoint.y.toFloat()
)
mPath.cubicTo(
mSecondCurveControlPoint1.x.toFloat(), mSecondCurveControlPoint1.y.toFloat(),
mSecondCurveControlPoint2.x.toFloat(), mSecondCurveControlPoint2.y.toFloat(),
mSecondCurveEndPoint.x.toFloat(), mSecondCurveEndPoint.y.toFloat()
)
mPath.lineTo(mNavigationBarWidth.toFloat(), 0F)
mPath.lineTo(mNavigationBarWidth.toFloat(), mNavigationBarHeight.toFloat())
mPath.lineTo(0F, mNavigationBarHeight.toFloat())
mPath.close()
}
override fun onDraw(canvas: Canvas) {
super.onDraw(canvas)
canvas.drawPath(mPath, mPaint)
}
}
직접 드로우 되는걸 커스텀 뷰에서 Path와 Paint를 이용해서 그려주는 것 같다.
클릭되는 메뉴 아이템이 실제 구현 화면에선 두개인데 위의 소스를 통해 구현하기 위해선 세개를 넣어야 한다. 두개를 넣으면 뭉게지기 때문에 세개를 넣고 중간 버튼을 비활성화 시키는 방법을 사용한다.
레이아웃 코드
<FullPackageName.CustomBottomNavigationView
android:id="@+id/bottom_navigation"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#FFFFFF"
android:layout_gravity="bottom"
app:labelVisibilityMode="labeled"/>
728x90
반응형
'App > 개발' 카테고리의 다른 글
안드로이드 AlertDialog 띄우기 (0) | 2020.08.24 |
---|---|
코틀린 팝업메뉴 코드 저장 (0) | 2020.08.24 |
안드로이드 공유링크 만들기 (0) | 2020.08.14 |
코틀린 안드로이드 위도, 경도 값 받아서 현재 주소로 변환하기 (0) | 2020.07.17 |
코틀린 커스텀 뷰 캘린더 레이아웃, 클래스 코드 (0) | 2020.07.16 |