Find Interaction Controller
Supported Platforms: AndroidiOSmacOS
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.
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.
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
- iOS


Did you find it useful? Consider making a donation to support this project and leave a star on GitHub . Your support is really appreciated!