Согласно этого блога, при использовании Navigator 2.0 и/или (в моем случае) GoRouter вы больше не можете переопределять кнопку возврата телефона с помощью вызова функции «WillPopScope» и onWillPop. Navigator 2.0 теперь использует PopRoute для возврата.
Это вызывает проблему при использовании веб-просмотра на флаттер-странице. Если пользователь переходит на другую веб-страницу в этом веб-представлении, а затем нажимает кнопку «Назад» на своем телефоне, он, естественно, ожидает, что веб-представление вернется к предыдущей веб-странице. Но вместо этого он уводит пользователя с этой страницы и возвращает на предыдущую страницу флаттера.
Есть ли способ обойти это? Могу ли я, чтобы моя кнопка «Назад» сначала проверила, есть ли контроллер.canGoBack(), как я раньше мог делать со старой системой Navigator?
Я нашел решение. Замысловато, но функционально:
Мне пришлось создать собственный «backButtonDispatcher» и добавить его в функцию main.dart MaterialApp.router.
child: Builder(builder: (BuildContext context) {
final router = Provider.of<MainRouter>(context, listen: false).router;
backbuttondispatcher = backButtonDispatcher(router.routerDelegate, settings);
return MaterialApp.router(
routeInformationParser: router.routeInformationParser,
routeInformationProvider: router.routeInformationProvider,
routerDelegate: router.routerDelegate,
backButtonDispatcher: backbuttondispatcher,
.
.
.
Я создал новый диспетчер в папке маршрутизатора и назвал его «backbuttondispatcher.dart.
import 'package:flutter/material.dart';
class backButtonDispatcher extends RootBackButtonDispatcher {
final RouterDelegate _routerDelegate;
final _settings;
backButtonDispatcher(this._routerDelegate,this._settings)
: super();
Future<bool> didPopRoute() async {
//Can user leave the page?
if (!_settings.canLeavePage) {
//no, as the webview widget has flagged canLeavePage as false
_settings.goBackToPreviousWebsite();
return true;
}else{
//yes, perform standard popRoute call
return _routerDelegate.popRoute();
}
}
}
Используя ссылку на общий класс (я использовал «_settings»), я сохраняю флаг, который говорит, прошел ли пользователь более одной веб-страницы — если TRUE, диспетчер кнопки «Назад» не вернется к предыдущему маршруту/странице. и вместо этого вызовите другую функцию (указатель), которая обрабатывает возврат к предыдущей веб-странице в маршруте виджета веб-просмотра. Но если FALSE, диспетчер выполняет стандартную функцию didPopRoute.
Кроме того, на всех других маршрутах/страницах с веб-просмотром функция указателя и логическое значение должны сбрасываться на нуль и ложь. Это не идеально, но, к счастью, в приложении не так много страниц.
Меня раздражает, что они изменили функциональность кнопки «Назад» для навигации по основному маршруту/странице, но не приняли во внимание тот факт, что кнопку «Назад» также можно использовать для возврата на предыдущую веб-страницу. Я понимаю, что нам в любом случае не следует показывать веб-страницы с приложениями, но мы, простые разработчики, не всегда имеем возможность отклонить требования приложений сверху.