---
title: "在 Flutter SDK 中展示用户引导"
description: "了解如何有效展示用户引导以提升转化率。"
---

:::warning
**用户引导功能已在 SDK v4 中弃用，并将在未来版本中移除。** 该功能不再接受修复或改进。请改用 [flows](flutter-get-pb-paywalls)：与在 WebView 中运行的用户引导不同，flows 直接在设备上原生渲染，带来更流畅的动画、一致的原生外观体验、更快的加载速度，且无需依赖 WebView 运行时。请参阅 [获取 flows 与付费墙](flutter-get-pb-paywalls) 和 [展示 flows 与付费墙](flutter-present-paywalls) 快速上手。
:::
如果您已使用编辑工具自定义了用户引导，则无需在 Flutter 应用代码中手动处理渲染逻辑来向用户展示它。这类用户引导已包含展示内容与展示方式的完整配置。

开始之前，请确认以下事项：

1. 您已安装 [Adapty Flutter SDK](sdk-installation-flutter) 3.8.0 或更高版本。
2. 您已[创建用户引导](create-onboarding)。
3. 您已将用户引导添加到[版位](placements)。

Adapty Flutter SDK 提供两种展示用户引导的方式：

- **独立页面**

- **嵌入式组件**
## 以独立屏幕呈现 \{#present-as-standalone-screen\}

要将用户引导以独立屏幕的形式展示，请对 `createOnboardingView` 方法创建的 `onboardingView` 调用 `onboardingView.present()` 方法。每个 `view` 只能使用一次。如果需要再次展示用户引导，请重新调用 `createOnboardingView` 创建一个新的 `onboardingView` 实例。

:::warning
重复使用同一个 `onboardingView` 而不重新创建，可能会导致 `AdaptyUIError.viewAlreadyPresented` 错误。
:::
```dart showLineNumbers title="Flutter"
try {
  await onboardingView.present();
} on AdaptyError catch (e) {
  // handle the error
} catch (e) {
  // handle the error
}
```

### 关闭用户引导 \{#dismiss-the-onboarding\}

当需要以编程方式关闭用户引导时，请使用 `dismiss()` 方法：

```dart showLineNumbers title="Flutter"
try {
  await onboardingView.dismiss();
} on AdaptyError catch (e) {
  // handle the error
} catch (e) {
  // handle the error
}
```

### 配置 iOS 展示样式 \{#configure-ios-presentation-style\}

通过向 `present()` 方法传入 `iosPresentationStyle` 参数，可配置用户引导在 iOS 上的展示方式。该参数接受 `AdaptyUIIOSPresentationStyle.fullScreen`（默认值）或 `AdaptyUIIOSPresentationStyle.pageSheet` 值。

```dart showLineNumbers
try {
  await onboardingView.present(iosPresentationStyle: AdaptyUIIOSPresentationStyle.pageSheet);
} on AdaptyError catch (e) {
  // handle the error
} catch (e) {
  // handle the error
}
```

## 嵌入到 Widget 层级中 \{#embed-in-widget-hierarchy\}

若要将用户引导嵌入到现有的 Widget 树中，可直接在 Flutter Widget 层级里使用 `AdaptyUIOnboardingPlatformView` 组件。
```dart showLineNumbers title="Flutter"
AdaptyUIOnboardingPlatformView(
  onboarding: onboarding, // The onboarding object you fetched
  onDidFinishLoading: (meta) {
  },
  onDidFailWithError: (error) {
  },
  onCloseAction: (meta, actionId) {
  },
  onPaywallAction: (meta, actionId) {
  },
  onCustomAction: (meta, actionId) {
  },
  onStateUpdatedAction: (meta, elementId, params) {
  },
  onAnalyticsEvent: (meta, event) {
  },
)
```

:::note 
要使 Android 平台视图正常工作，请确保你的 `MainActivity` 继承自 `FlutterFragmentActivity`：
```kotlin showLineNumbers title="Kotlin"
class MainActivity : FlutterFragmentActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
    }
}
```
:::

## 用户引导加载中 \{#loader-during-onboarding\}

展示用户引导时，你可能会注意到在启动画面和用户引导之间有一个短暂的加载界面，这是底层视图初始化时产生的。你可以根据自己的需求，用不同的方式来处理这个问题。

#### 使用 onDidFinishLoading 控制启动画面 \{#control-splash-screen-using-ondidfinishloading\}

:::note
该方式仅在将用户引导作为 widget 嵌入时可用，不支持以独立页面方式展示。
:::
推荐的跨平台方案是：保持启动屏或自定义遮罩可见，直到用户引导完全加载后，再手动将其隐藏。

使用嵌入式 widget 时，在其上方叠加自定义 widget，并在 `onDidFinishLoading` 触发时隐藏遮罩：

```dart showLineNumbers title="Flutter"
AdaptyUIOnboardingPlatformView(
  onboarding: onboarding,
  onDidFinishLoading: (meta) {
    // Hide your custom splash screen or overlay here
  },
  // ... other callbacks
)
```
### 自定义原生加载界面 \{#customize-native-loader\}

:::important
此方式与平台相关，需要维护原生 UI 代码。除非您的应用已维护独立的原生层，否则不建议使用。
:::

如果需要自定义默认加载界面本身，可以使用平台专属布局进行替换。此方式需要分别针对 Android 和 iOS 进行实现：

- **iOS**：将 `AdaptyOnboardingPlaceholderView.xib` 添加到您的 Xcode 项目中
- **Android**：在 `res/layout` 中创建 `adapty_onboarding_placeholder_view.xml` 并在其中定义占位视图

## 自定义用户引导中的链接打开方式 \{#customize-how-links-open-in-onboardings\}

:::important
自定义用户引导中链接的打开方式需要 Adapty SDK v3.15.1 及以上版本。
:::

默认情况下，用户引导中的链接会在应用内浏览器中打开。这样可以在应用内直接展示网页，用户无需切换应用，体验更流畅。

如果你希望在外部浏览器中打开链接，可以将 `externalUrlsPresentation` 参数设置为 `AdaptyWebPresentation.externalBrowser` 来自定义此行为：
<Tabs>
<TabItem value="standalone" label="独立页面" default>

```dart showLineNumbers title="Flutter"
final onboardingView = await AdaptyUI().createOnboardingView(
  onboarding: onboarding,
  externalUrlsPresentation: AdaptyWebPresentation.externalBrowser, // default – AdaptyWebPresentation.inAppBrowser
);

try {
  await onboardingView.present();
} on AdaptyError catch (e) {
  // handle the error
} catch (e) {
  // handle the error
}
```

</TabItem>
<TabItem value="embedded" label="嵌入式组件">
```dart showLineNumbers title="Flutter"
AdaptyUIOnboardingPlatformView(
  onboarding: onboarding,
  externalUrlsPresentation: AdaptyWebPresentation.externalBrowser, // default – AdaptyWebPresentation.inAppBrowser
  onDidFinishLoading: (meta) {
  },
  onDidFailWithError: (error) {
  },
  onCloseAction: (meta, actionId) {
  },
  onPaywallAction: (meta, actionId) {
  },
  onCustomAction: (meta, actionId) {
  },
  onStateUpdatedAction: (meta, elementId, params) {
  },
  onAnalyticsEvent: (meta, event) {
  },
)
```

</TabItem>
</Tabs>
## 禁用安全区域内边距（Android） \{#disable-safe-area-paddings-android\}

默认情况下，在 Android 设备上，用户引导视图会自动应用安全区域内边距，以避免与状态栏、导航栏等系统 UI 元素重叠。如果你想禁用此行为并完全自定义布局，可以在应用中添加一个布尔值资源：

1. 进入 `android/app/src/main/res/values` 目录。如果没有 `bools.xml` 文件，请新建一个。

2. 添加以下资源：

```xml
<resources>
    <bool name="adapty_onboarding_enable_safe_area_paddings">false</bool>
</resources>
```
请注意，这些更改会全局应用于你应用中的所有用户引导。