This guide covers creating a minimal platform adapter and using it with NutrientView.

Prerequisites

Set up a working Nutrient Flutter project before using platform adapters. For more information, refer to the Flutter getting started guide.

Requirements

Flutter:

  • Flutter SDK 3.27.0 or later
  • Dart SDK 3.6.0 or later

Android:

  • Android Studio (latest stable version)
  • Android NDK
  • Minimum SDK version: 21
  • Compile SDK version: 35
  • Java 17

iOS:

  • Xcode 16 or later
  • iOS 16.0 or later
  • CocoaPods

Web:

  • Chrome, Firefox, Safari, or Edge (latest stable version)
  • A Nutrient Web SDK license or trial

Creating a configuration adapter

The simplest adapter overrides the configuration hook to customize how the native SDK initializes. This example doesn’t include a controller interface or event handling.

lib/adapters/my_android_adapter.dart
import 'package:nutrient_flutter_android/src/android_platform_adapter.dart';
import 'package:nutrient_flutter_android/src/bindings/nutrient_android_sdk_bindings.dart'
as android;
class MyAndroidAdapter extends AndroidAdapter {
@override
Future<void> configureFragment(
NutrientViewHandle handle,
android.PdfUiFragmentBuilder builder,
android.Context context,
) async {
await super.configureFragment(handle, builder, context);
final config =
android.PdfActivityConfiguration$Builder(context)
.layoutMode(android.PageLayoutMode.SINGLE)
.scrollDirection(
android.PageScrollDirection.VERTICAL)
.fitMode(android.PageFitMode.FIT_TO_WIDTH)
.searchEnabled(true)
.annotationEditingEnabled(true)
.build();
builder.configuration(config);
}
@override
Future<void> onFragmentAttached(
android.PdfUiFragment fragment,
android.Context context,
) async {}
@override
Future<void> onPdfFragmentReady(
android.PdfFragment pdfFragment) async {}
@override
Future<void> onFragmentDetached() async {}
}

Using the adapter with NutrientView

Pass the adapter to NutrientView via the adapter parameter. Use the conditional import factory pattern to create the correct adapter for the current platform. For more information, refer to platform imports.

import 'package:flutter/material.dart';
import 'package:nutrient_flutter/nutrient_flutter.dart';
// Conditional import resolves to the correct platform factory.
import 'adapters/adapters.dart';
class AdapterExample extends StatelessWidget {
final String documentPath;
const AdapterExample({super.key, required this.documentPath});
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: const Text('PDF Viewer')),
body: NutrientView(
documentPath: documentPath,
adapter: createAdapter(),
),
);
}
}

Verifying installation

Run your app to verify the adapter is working:

Terminal window
# Android
flutter run -d android
# iOS
flutter run -d ios
# Web
flutter run -d chrome

The PDF viewer displays your document with the native SDK configuration applied by your adapter.

Troubleshooting

This section addresses common issues with platform imports and adapter lifecycle callbacks.

Import errors when building for a different platform

If you see errors like Target of URI doesn't exist or Dart library 'dart:io' is not available on this platform, your adapter files are importing bindings for the wrong platform. Each adapter file imports only its own platform’s bindings. For more information, refer to platform imports.

Adapter not receiving lifecycle callbacks

Verify that the adapter is passed to NutrientView via the adapter parameter. If the adapter’s lifecycle methods (onPdfFragmentReady, onViewControllerReady, onInstanceLoaded) aren’t being called, check that the adapter is the correct type for the current platform.

Next steps