跳过主要内容
返回插件
@capgo/capacitor-native-navigation
教程
@capgo/capacitor-native-navigation

原生导航

在全屏 Capacitor WebView 上渲染原生导航栏、标签栏和过渡壳

演示

动画WebP演示

原生导航栏、选项卡选择、SVG图标和样式选项渲染为动画WebP演示。

源资产
原生导航栏、选项卡和WebView内容的动画原生导航栏演示
原生shell
选项卡选择、推送过渡和原生后退的动画原生导航栏点击流演示
动画原生导航点击流
动态原生 SVG 图标示例,展示内联 SVG 图标、原生颜色、标签和选项卡选择
SVG 图标
动态原生导航选项示例,展示动态颜色、选中标签、徽章和缩放过渡
样式选项

指南

原生导航教程

在设备上测试

下载 Capgo 应用程序,然后扫描 QR code。

原生导航插件预览二维码 code

使用 @capgo/capacitor-native-navigation

@capgo/capacitor-native-navigation 渲染原生顶部导航栏、底部标签栏和路由转场壳,覆盖在一个全屏 Capacitor WebView 上。您的 Web 框架仍然拥有路由和内容,而原生则拥有应用框架。

安装并同步

npm install @capgo/capacitor-native-navigation
npx cap sync

配置原生框架

import { NativeNavigation } from '@capgo/capacitor-native-navigation';

await NativeNavigation.configure({
  contentInsetMode: 'css',
  animationDuration: 360,
  colors: {
    tint: '#0f172a',
    inactiveTint: '#64748b',
  },
});

渲染原生导航栏

await NativeNavigation.setNavbar({
  title: 'Inbox',
  subtitle: 'Native chrome',
  transparent: true,
  backButton: { visible: false },
  rightItems: [
    {
      id: 'compose',
      title: 'Compose',
      icon: {
        svg: '<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M12 20h9"/><path d="M16.5 3.5a2.12 2.12 0 0 1 3 3L7 19l-4 1 1-4Z"/></svg>',
      },
    },
  ],
});

渲染原生标签栏

await NativeNavigation.setTabbar({
  selectedId: 'inbox',
  labelVisibilityMode: 'selected',
  icons: true,
  colors: {
    dynamic: true,
    tint: '#0f172a',
    inactiveTint: '#64748b',
  },
  tabs: [
    {
      id: 'inbox',
      title: 'Inbox',
      icon: {
        svg: '<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M4 4h16v16H4z"/><path d="m4 13 4 4h8l4-4"/></svg>',
      },
    },
    {
      id: 'search',
      title: 'Search',
      icon: {
        svg: '<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><circle cx="11" cy="11" r="7"/><path d="m20 20-3-3"/></svg>',
      },
    },
  ],
});

将原生事件连接到您的路由器

原生栏发射意图。您的路由器仍然执行路由更改:

await NativeNavigation.addListener('navbarBack', () => {
  router.back();
});

await NativeNavigation.addListener('navbarItemTap', ({ id }) => {
  if (id === 'compose') router.push('/compose');
});

await NativeNavigation.addListener('tabSelect', ({ id }) => {
  router.push(`/${id}`);
});

动画路由更改

在您的正常 Web 路由更新周围使用一个转场事务:

const transition = await NativeNavigation.beginTransition({
  direction: 'forward',
});

router.push('/message/42');
await router.ready?.();

await NativeNavigation.setNavbar({
  title: 'Message',
  backButton: { visible: true, title: 'Inbox' },
});

await NativeNavigation.finishTransition({
  id: transition.id,
  direction: 'forward',
});

添加缩放过渡

在从卡片、网格项或媒体预览打开的路由中使用缩放辅助功能。

import { beginZoomTransition, finishZoomTransition } from '@capgo/capacitor-native-navigation';

const card = document.querySelector('[data-message-card]');
if (card) {
  const transition = await beginZoomTransition(card, { cornerRadius: 18 });

  router.push('/message/42');
  await router.ready?.();

  await NativeNavigation.setNavbar({
    title: 'Message',
    backButton: { visible: true, title: 'Inbox' },
  });

  await finishZoomTransition(undefined, {
    id: transition.id,
    cornerRadius: 18,
  });
}

使用原生边距填充内容

contentInsetMode 时,插件为原生栏写入CSS变量: css图标选择

.page {
  padding-top: var(--cap-native-navigation-top);
  padding-bottom: var(--cap-native-navigation-bottom);
}

图标是原生的描述符,而不是React或Vue节点。使用SVG时不想打包原生资产时使用:

内联SVG支持

const icon = {
  svg: '<svg viewBox="0 0 24 24"><path d="M3 10.5 12 3l9 7.5"/></svg>',
  template: true,
  ios: { sfSymbol: 'house.fill' },
  android: { resource: 'ic_menu_view' },
};

,和 path, line, polyline, polygon, circle,这涵盖了常见的图标集,如Lucide和Feather。 rect结合@__CAPGO_KEEP_0__/__CAPGO_KEEP_1__-transitions

Combine with @capgo/capacitor-transitions

使用原生导航来使用原生导航栏、标签栏、安全区域内边距和原生意图事件。使用 @capgo/capacitor-transitions 用于 WebView 页面堆栈底部的原生浏览器。

npm install @capgo/capacitor-native-navigation @capgo/capacitor-transitions
npx cap sync

初始化两次包:

import { NativeNavigation } from '@capgo/capacitor-native-navigation';
import '@capgo/capacitor-transitions';
import { initTransitions, setupRouterOutlet, setDirection } from '@capgo/capacitor-transitions/react';

initTransitions({ platform: 'auto' });

const outlet = document.querySelector('cap-router-outlet');
if (outlet) {
  setupRouterOutlet(outlet, { platform: 'auto', swipeGesture: 'auto' });
}

await NativeNavigation.configure({
  contentInsetMode: 'css',
});

将过渡输出焦点放在页面上,而不是重复的 Web 条:

<cap-router-outlet platform="auto" swipe-gesture="auto">
  <cap-page>
    <cap-content slot="content" fullscreen>
      <main class="page">Inbox content</main>
    </cap-content>
  </cap-page>
</cap-router-outlet>

从同一个路由动作驱动两次包:

async function openMessage(id: string) {
  setDirection('forward');
  await router.push(`/messages/${id}`);
  await NativeNavigation.setNavbar({
    title: 'Message',
    backButton: { visible: true, title: 'Inbox' },
  });
}

await NativeNavigation.addListener('navbarBack', () => {
  setDirection('back');
  router.back();
});

await NativeNavigation.addListener('tabSelect', ({ id }) => {
  setDirection('root');
  router.push(`/${id}`);
});

选择每次路由变化的动画层。让 @capgo/capacitor-transitions 正常页面推送动画,仅使用原生导航的缩放助手来处理共享元素或缩放路由。

完整参考

继续使用@capgo/capacitor-native-navigation

如果您正在使用 使用@capgo/capacitor-native-navigation 来规划原生媒体和界面行为,连接它与 @capgo/capacitor-native-navigation 了解@capgo/capacitor-native-navigation的实现细节在 Getting Started 了解Getting Started的实现细节在 使用@capgo/capacitor-live-activities 原生能力的@capgo/capacitor-live-activities @capgo/capacitor-live-activities 了解@capgo/capacitor-live-activities的实现细节, 使用@capgo/capacitor-video-player 为原生能力在使用 @capgo/capacitor-video-player。