CustomBottomNav
최종 이미지
코드
import com.google.android.material.bottomnavigation.BottomNavigationView
import android.content.Context
import android.util.AttributeSet
import androidx.core.content.ContextCompat
import android.graphics.*
import com.telefield.iot_user_app.R
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.gray_100)
mPaint.setShadowLayer(12F, 0F, 0F, Color.BLACK)
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.drawRect(20F, 20F, 100F, 100F, mPaint)
canvas.drawPath(mPath, mPaint)
}
}
xml에서는 BottomNavigationView를 CustomBottomNavigationView로 변경하면 된다.
그림자를 제거하고 싶으면 init 함수에서 mPaint.setShadowLayer()과 onDraw 함수에서 canvas.drawRect() 부분을 지우면 된다.
참고로 가운데 버튼은 FloatingActionButton으로 만들었습니다.
'안드로이드 > Design' 카테고리의 다른 글
Figma로 앱 설계 (다크모드) (0) | 2023.03.02 |
---|---|
android shared elements transition (0) | 2022.10.20 |