Понимание Future и Completer во Flutter.... Как использовать контроллер для загрузки нового URL-адреса из веб-просмотра

Я не могу загрузить новый URL-адрес в веб-просмотре флаттера... У меня проблемы с использованием then и Future в контроллере флаттера Webview...

В трепете Webview я хотел бы загрузить initialUrl, а затем программно получить некоторую информацию с этой веб-страницы... Пока все работает хорошо... Но затем я хочу, чтобы Webview автоматически загружал другую веб-страницу... но я не уверен, как использовать controller и Completer для этого

Фрагмент:

WebView(
  initialUrl: 'https://flutter.dev',
  onWebViewCreated: (WebViewController webViewController) {
    _controller.complete(webViewController);
    },
  onPageFinished: (String url) async{
    if (url == 'https://flutter.dev') {
      // *** I retrieve some data, then I want to navigate ***
      _controller!.loadUrl('https://google.com'); // *** ERROR HERE ***
    }
  },
)

Я пытался использовать controller напрямую,

_controller!.loadUrl('https://google.com');

это работает, если я не использую Completer , а вместо этого просто назначаю controller

_controller = webViewController;

но не кажется рекомендуемым вариантом:

Я нашел другие примеры с использованием FutureBuilder, но я не пытаюсь ничего построить.

Вот полный код, на всякий случай:

import 'package:flutter/material.dart';
import 'package:webview_flutter/webview_flutter.dart';
import 'dart:async';

void main() {
  runApp(
    const MaterialApp(
      home: WebViewApp(),
    ),
  );
}

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

  @override
  State<WebViewApp> createState() => _WebViewAppState();
}

class _WebViewAppState extends State<WebViewApp> {
  final Completer<WebViewController> _controller = Completer<WebViewController>();
  
  @override Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text('Flutter WebView'),),
      body: WebView(
        initialUrl: 'https://flutter.dev',
        onWebViewCreated: (WebViewController webViewController) {
          _controller.complete(webViewController);
          },
        onPageFinished: (String url) async{
          if (url == 'https://flutter.dev') {
            // *** I retrieve some data, then I want to navigate ***
            _controller!.loadUrl('https://google.com'); // *** ERROR HERE ***
          }
        },
      ),
    );
  }
}
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
6
0
355
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

на предмет того, как использовать комплектующее в этом случае!

Замените обратный вызов onPageFinished следующим фрагментом и внимательно прочитайте комментарии.

  onPageFinished: (String url) async{
              // add the missing '/' at the end of the url since the url string is 'https://flutter.dev/' 
              // NOT 'https://flutter.dev'
              if (url == 'https://flutter.dev/') {
                // *** I retrieve some data, then I want to navigate ***
                final wvController = await _controller.future;
                await wvController.loadUrl('https://google.com');
                // ***
                // No More ERROR
                // HERE ***)
              }
            },

Спасибо @Saed Nabil ... Это то, что я искал ... Не могли бы вы порекомендовать, следует ли мне использовать средство завершения контроллера (как в документации Webview) или я должен использовать только контроллер, как в ответе Онура ниже?? На самом деле, он отлично работает без завершения, и другие мои анимации (здесь не показаны) не отстают, как при использовании дополнения.

Canada2000 20.11.2022 01:36

@ Canada2000 Спасибо, я рекомендую пока придерживаться документации, так как она более безопасна, и если вы заинтересованы, пожалуйста, откройте еще один вопрос о вашей проблеме с анимацией, может быть, мы сможем вам больше помочь, мир!

Saed Nabil 20.11.2022 19:30

Лучший способ сделать это — использовать итераторы и контроллеры. Не нужно возиться с индексом. После вызова функции moveNext() URL-адрес в итераторе обновляется. Вы также можете открыть новый URL-адрес с помощью функции контроллера loadUrl().

import 'dart:io';

import 'package:flutter/material.dart';
import 'package:webview_flutter/webview_flutter.dart';

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

  @override
  State<SamplePage> createState() => _SamplePageState();
}

class _SamplePageState extends State<SamplePage> {
  late WebViewController _webViewController;
  Iterable<String> urlStrings = [
    'https://www.google.com/',
    'https://www.yahoo.com/',
    'https://www.bing.com/',
    'https://flutter.dev/',
    'https://altavista.com/'
  ];
  late Iterator<String> urlIterator;

  @override
  void initState() {
    super.initState();
    // init url iterator.
    urlIterator = urlStrings.iterator;
    urlIterator.moveNext();

    // Enable virtual display.
    if (Platform.isAndroid) WebView.platform = AndroidWebView();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: WebView(
        onWebViewCreated: (controller) => setState(() => _webViewController = controller),
        initialUrl: urlIterator.current,
        onPageFinished: (url) {
          urlIterator.moveNext();
          _webViewController.loadUrl(urlIterator.current);
        },
      ),
    );
  }
}

спасибо @Onur ... Это работает хорошо ... но, похоже, рекомендуется использовать «Cmpleter» (хотя я не уверен)

Canada2000 20.11.2022 01:38

Другие вопросы по теме