Skip to main content
Version: 6.x.x

Find Interaction Controller

FindInteractionController represents the controller used by the WebView to add text-finding capabilities, such as the "Find on page" feature.

Basic Usage

Set the findInteractionController of the WebView to control the text-finding feature. To start search text, use findInteractionController.findAll(string find) and then use findInteractionController.findNext(bool forward) to move forward (true) or backward (false ).

You can access the active find session with findInteractionController.getActiveFindSession() with info about the search after completion.

Note for Android

The findAll method will not wait for the completion of the search.

In this case, you can wait for a little time, for example await Future.delayed(Duration(seconds: 1))), before accessing the active FindSession.

Also, you can listen for the FindInteractionController.onFindResultReceived event that is an event fired as find-on-page operations progress.

Note for iOS

This event will not be called if InAppWebViewSettings.isFindInteractionEnabled is true.

Only on iOS, setting InAppWebViewSettings.isFindInteractionEnabled to true, enables the web view's built-in find interaction native UI. With this option enabled, you can use the other FindInteractionController methods to control the iOS native UI.

Example:

import 'dart:async';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:flutter_inappwebview/flutter_inappwebview.dart';

Future main() async {
WidgetsFlutterBinding.ensureInitialized();

if (!kIsWeb && defaultTargetPlatform == TargetPlatform.android) {
await InAppWebViewController.setWebContentsDebuggingEnabled(kDebugMode);
}

runApp(const MaterialApp(home: MyApp()));
}

class MyApp extends StatefulWidget {
const MyApp({super.key});


State<MyApp> createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
final GlobalKey webViewKey = GlobalKey();

InAppWebViewController? webViewController;
InAppWebViewSettings settings = InAppWebViewSettings();
late FindInteractionController findInteractionController;
final searchController = TextEditingController();
var textFound = "";


void initState() {
super.initState();

findInteractionController = FindInteractionController(
onFindResultReceived: (controller, activeMatchOrdinal, numberOfMatches,
isDoneCounting) async {
if (isDoneCounting) {
setState(() {
textFound = numberOfMatches > 0
? '${activeMatchOrdinal + 1} of $numberOfMatches'
: '';
});
if (numberOfMatches == 0) {
ScaffoldMessenger.of(context).showSnackBar(SnackBar(
content: Text(
'No matches found for "${await findInteractionController.getSearchText()}"'),
));
}
}
},
);
}


Widget build(BuildContext context) {
var isFindInteractionEnabled = settings.isFindInteractionEnabled ?? false;

return Scaffold(
appBar: AppBar(
title: const Text('Find Interaction Controller'),
actions: defaultTargetPlatform != TargetPlatform.iOS
? []
: [
(isFindInteractionEnabled)
? IconButton(
icon: const Icon(Icons.search),
onPressed: () async {
if (await findInteractionController
.isFindNavigatorVisible() ??
false) {
await findInteractionController
.dismissFindNavigator();
} else {
await findInteractionController
.presentFindNavigator();
}
},
)
: Container(),
TextButton(
style:
TextButton.styleFrom(foregroundColor: Colors.white),
onPressed: () async {
if (isFindInteractionEnabled) {
searchController.text =
await findInteractionController.getSearchText() ??
'';
}
await findInteractionController.clearMatches();
isFindInteractionEnabled =
settings.isFindInteractionEnabled =
!isFindInteractionEnabled;
await webViewController?.setSettings(
settings: settings);
setState(() {
textFound = '';
});
await findInteractionController
.setSearchText(searchController.text);
if (isFindInteractionEnabled) {
await findInteractionController
.presentFindNavigator();
}
},
child: Text(!isFindInteractionEnabled
? 'Native UI'
: 'Custom UI'),
)
]),
body: Column(children: <Widget>[
isFindInteractionEnabled
? Container()
: TextField(
decoration: InputDecoration(
prefixIcon: const Icon(Icons.search),
suffixText: textFound,
suffixIcon: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
mainAxisSize: MainAxisSize.min,
children: <Widget>[
const SizedBox(
width: 10,
),
IconButton(
icon: const Icon(Icons.arrow_upward),
onPressed: () {
findInteractionController.findNext(forward: false);
},
),
IconButton(
icon: const Icon(Icons.arrow_downward),
onPressed: () {
findInteractionController.findNext();
},
),
],
),
),
controller: searchController,
keyboardType: TextInputType.text,
onSubmitted: (value) {
if (value == '') {
findInteractionController.clearMatches();
setState(() {
textFound = '';
});
} else {
findInteractionController.findAll(find: value);
}
},
),
Expanded(
child: InAppWebView(
key: webViewKey,
initialUrlRequest: URLRequest(url: WebUri("https://flutter.dev/")),
findInteractionController: findInteractionController,
initialSettings: settings,
onWebViewCreated: (InAppWebViewController controller) {
webViewController = controller;
},
)),
]));
}
}

This is the result:

Android find interaction controller basic usage