0

I set the bulge for BottomNavigationView through the set to edge method of materialShapeDrawable, because the color of the page is similar to that of BottomNavigationView, so I need to set a border or shadow on top of the control, but I can't set the border or shadow on top of the control normally.

In addition, bottomNavigationView.invalidateOutline() seems to have some effect, but it seems to be only valid on Android12, and the lower version of Android cannot be used.

val materialShapeDrawable = bottomNavigationView.background as MaterialShapeDrawable materialShapeDrawable.shapeAppearanceModel = materialShapeDrawable.shapeAppearanceModel
                .toBuilder()
                .setTopEdge(CutoutCircleEdgeTreatment(resources, 70.toFloat(), 10.toFloat()))
                .build()
            val backgroundDrawable =
                MaterialShapeDrawable(materialShapeDrawable.shapeAppearanceModel).apply {
                    setTint(Color.WHITE)
                    paintStyle = Paint.Style.FILL
                    shadowCompatibilityMode = MaterialShapeDrawable.SHADOW_COMPAT_MODE_ALWAYS
                    initializeElevationOverlay(this@MainActivity)
                    setShadowColor(Color.RED)
                    elevation = 100F
                }
            (bottomNavigationView.parent as? ViewGroup)?.clipChildren = false
            bottomNavigationView.background = backgroundDrawable
            bottomNavigationView.invalidateOutline()
    
    
        class CutoutCircleEdgeTreatment(
            res: Resources,
            circleDiameterDp: Float,
            circleLeftRightOffsetDp: Float
        ) : EdgeTreatment() {
    
            private val fabDiameter: Float
            private val offset: Float
    
            init {
                fabDiameter = TypedValue.applyDimension(
                    TypedValue.COMPLEX_UNIT_DIP,
                    circleDiameterDp,
                    res.displayMetrics
                )
                offset = TypedValue.applyDimension(
                    TypedValue.COMPLEX_UNIT_DIP,
                    circleLeftRightOffsetDp,
                    res.displayMetrics
                )
            }
    
            override fun getEdgePath(
                length: Float,
                center: Float,
                interpolation: Float,
                shapePath: ShapePath
            ) {
                //凸起半径
                val r = length / 10 // == center
                val halfLine = length / 2 - r
                //值越大转角处就越顺滑,但是必须小于等于r,这个大小可以多试试
                val offset = 30f
                //第一部分,直线,画到凹陷开始的地方
                shapePath.lineTo(halfLine - offset, 0f)
                //凸起开始的地方的转角,不处理的话看起来很尖锐
                shapePath.quadToPoint(halfLine, 0f, halfLine + offset, -offset)
                //凸起部分
                shapePath.quadToPoint(center, -r, halfLine + 2 * r - offset, -offset)
                //凸起结束的地方的转角
                shapePath.quadToPoint(halfLine + 2 * r, 0f, halfLine + 2 * r + offset, 0f)
    //            最后一部分的直线,画到底
                shapePath.lineTo(length, 0f)
            }
        }

enter image description here enter image description here

Dr Mido
  • 2,414
  • 4
  • 32
  • 72
huilei
  • 1
  • 1

0 Answers0