You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何实现自定义导航栏?首次开发该导航的技术求助

自定义弧形导航栏实现指引

核心思路

这类带弧形底部+中间凸起按钮的导航栏,核心是通过自定义Drawable/自定义View绘制底部弧形路径,再配合布局层级放置悬浮的中间按钮。


具体实现步骤

1. 绘制底部弧形背景

以Android为例,用自定义Drawable实现弧形背景:

class CurvedNavBackground @JvmOverloads constructor(
    context: Context? = null,
    attrs: AttributeSet? = null
) : Drawable() {
    private val paint = Paint(Paint.ANTI_ALIAS_FLAG).apply {
        color = Color.WHITE // 导航栏背景色,可替换
        style = Paint.Style.FILL
    }
    private val path = Path()

    override fun draw(canvas: Canvas) {
        val width = bounds.width().toFloat()
        val height = bounds.height().toFloat()
        val curveRadius = height * 0.3f // 弧形曲率,可调整

        path.reset()
        // 左上角起点
        path.moveTo(0f, 0f)
        // 左侧边到弧形
        path.lineTo(0f, height - curveRadius)
        path.quadTo(0f, height, curveRadius, height)
        // 左侧弧形到中间凹口
        val buttonWidth = 60f // 中间按钮宽度
        val leftCurveEnd = (width / 2) - buttonWidth / 2 - curveRadius
        path.lineTo(leftCurveEnd, height)
        // 绘制中间下凹弧形
        path.quadTo((width/2)-buttonWidth/2, height - curveRadius, width/2, height - curveRadius)
        path.quadTo((width/2)+buttonWidth/2, height - curveRadius, (width/2)+buttonWidth/2 + curveRadius, height)
        // 右侧弧形到右下角
        path.lineTo(width - curveRadius, height)
        path.quadTo(width, height, width, height - curveRadius)
        // 右侧边到右上角
        path.lineTo(width, 0f)
        path.close()

        canvas.drawPath(path, paint)
    }

    override fun setAlpha(alpha: Int) {
        paint.alpha = alpha
        invalidateSelf()
    }

    override fun setColorFilter(colorFilter: ColorFilter?) {
        paint.colorFilter = colorFilter
        invalidateSelf()
    }

    override fun getOpacity(): Int = PixelFormat.OPAQUE
}

2. 搭建布局结构

用RelativeLayout/ConstraintLayout组织导航栏,把中间按钮放在背景上层实现悬浮:

<RelativeLayout
    android:layout_width="match_parent"
    android:layout_height="60dp"
    android:background="@drawable/curved_nav_background">

    <!-- 左侧导航按钮 -->
    <ImageView
        android:id="@+id/nav_left"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentLeft="true"
        android:layout_centerVertical="true"
        android:layout_marginLeft="20dp"
        android:src="@drawable/ic_home" />

    <!-- 右侧导航按钮 -->
    <ImageView
        android:id="@+id/nav_right"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentRight="true"
        android:layout_centerVertical="true"
        android:layout_marginRight="20dp"
        android:src="@drawable/ic_profile" />

    <!-- 中间悬浮按钮 -->
    <ImageView
        android:id="@+id/nav_center"
        android:layout_width="60dp"
        android:layout_height="60dp"
        android:layout_centerHorizontal="true"
        android:layout_marginTop="-30dp" <!-- 向上偏移一半高度实现悬浮 -->
        android:background="@drawable/round_button_bg"
        android:src="@drawable/ic_add" />

</RelativeLayout>

3. 问题排查与优化

  • 若之前用自定义面板+Path失败,检查路径是否闭合、绘制顺序是否正确,或者是否把按钮放在了背景层下方
  • 弧形半径、按钮尺寸、颜色都可根据需求在代码/布局中修改
  • iOS平台思路类似:用UIBezierPath绘制弧形路径添加到导航栏layer,中间按钮调整frame实现悬浮

内容的提问来源于stack exchange,提问作者Pranav Ratusaria

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.24 23:32:49