Убедиться, что WebView открывает новый URL-адрес после нажатия на BottomBarItem (трепетание)

поэтому я пытался заставить свое приложение работать. Я хотел создать приложение для одного из моих веб-сайтов, используя Flutter, и пока все получается. единственная проблема заключается в том, что когда я нажимаю кнопку с надписью «статус», WebView не переходит на страницу, на которую я хочу, чтобы он перешел.

мой код:

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

void main() {
  runApp(const MyApp());
}

class MyApp extends StatefulWidget {
  const MyApp({Key? key}) : super(key: key);

  @override
  _MyAppState createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
  int _selectedIndex = 0;
  final List<String> _urls = [
    "https://minecraft.xandersalarie.com/",
    "https://minecraft.xandersalarie.com/status",
  ];

  void _onItemTapped(int index) {
    setState(() {
      _selectedIndex = index;
    });
  }

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      debugShowCheckedModeBanner: false,
      home: Scaffold(
        body: SafeArea(
          child: WebView(
            initialUrl: _urls[_selectedIndex],
            javascriptMode: JavascriptMode.unrestricted,
          ),
        ),
        bottomNavigationBar: BottomNavigationBar(
          items: const <BottomNavigationBarItem>[
            BottomNavigationBarItem(
              icon: Icon(Icons.home),
              label: 'Home',
            ),
            BottomNavigationBarItem(
              icon: Icon(Icons.stacked_bar_chart_outlined),
              label: 'Status',
            ),
          ],
          currentIndex: _selectedIndex,
          selectedItemColor: Colors.amber[800],
          onTap: _onItemTapped,
        ),
      ),
    );
  }
}

Я попробовал то, что прочитал в Интернете. Я прочитал, что до сих пор вы не можете использовать InitialUrl дважды, поэтому я обязательно использовал final List<String>_urls, поскольку это был единственный вариант, который я нашел. чего я ожидал, так это того, когда он будет на «доме». он начинается со страницы входа в систему, и когда я нажимаю «статус», он переходит на другой URL-адрес в списке. у меня этого не происходит. мне также хотелось бы, чтобы если вы нажмете «Домой», он обновит WebView, но он тоже этого не сделает.

0
0
59
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Вы можете использовать контроллер веб-просмотра и виджет веб-просмотра для контролируемой навигации по страницам.

Вы можете использовать официальный пакет веб-просмотра flutter.dev: https://pub.dev/packages/webview_flutter

Что-то вроде этого:

Отредактировано:

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

  @override
  _MyAppState createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
  int _selectedIndex = 0;
  final List<String> _urls = [
    "https://minecraft.xandersalarie.com/",
    "https://minecraft.xandersalarie.com/status",
  ];

  late final WebViewController controller;

  @override
  void initState() {
    controller = WebViewController()
      ..setJavaScriptMode(JavaScriptMode.unrestricted)
      ..setNavigationDelegate(
        NavigationDelegate(
          onNavigationRequest: (request) async {
            if (request.url.contains('https://minecraft.xandersalarie.com/')) {
              return NavigationDecision.navigate;
            }

            return NavigationDecision.prevent;
          },
        ),
      )
      ..loadRequest(Uri.parse(_urls[_selectedIndex]))
          .onError((error, stackTrace) => log(
        'error',
        error: error,
        stackTrace: stackTrace,
      ));
    super.initState();
  }

  void _onItemTapped(int index) {
    setState(() {
      _selectedIndex = index;
    });
    // This will load new url to the webview
    controller.loadRequest(Uri.parse(_urls[_selectedIndex]));
  }

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      debugShowCheckedModeBanner: false,
      home: Scaffold(
        body: SafeArea(
          child: WebViewWidget(
            controller: controller,
          ),
        ),
        bottomNavigationBar: BottomNavigationBar(
          items: const <BottomNavigationBarItem>[
            BottomNavigationBarItem(
              icon: Icon(Icons.home),
              label: 'Home',
            ),
            BottomNavigationBarItem(
              icon: Icon(Icons.stacked_bar_chart_outlined),
              label: 'Status',
            ),
          ],
          currentIndex: _selectedIndex,
          selectedItemColor: Colors.amber[800],
          onTap: _onItemTapped,
        ),
      ),
    );
  }
}

прежде всего спасибо за ответ! это помогло мне хотя бы загрузить страницу «minecraft.xandersalarie.com» при нажатии на страницу статуса. однако при запуске приложения страница остается белой, пока я не нажму «статус». и после того, как я нажимаю «Домой», он не возвращается к первому URL-адресу. Я пытался решить эту проблему, но, поскольку я новичок в трепетании, мне это не удалось.

RavenGaming 09.05.2024 13:55

Функция onNavigationRequest предотвращала перенаправление на ваш веб-сайт, поскольку URL-адрес перенаправляется с URL-адреса с индексом 0. Я изменил код, чтобы переходить только на ваш сайт и никуда больше.

Yashas Majmudar 10.05.2024 09:32
Ответ принят как подходящий

Используйте контроллер веб-просмотра для загрузки нового URL-адреса в веб-просмотр. Как указано в свойстве, для начального URL-адреса для загрузки нового URL-адреса используйте контроллер.

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

void main() {
  runApp(const MyApp());
}

class MyApp extends StatefulWidget {
  const MyApp({Key? key}) : super(key: key);

  @override
  _MyAppState createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
  int _selectedIndex = 0;
  final List<String> _urls = [
    "https://minecraft.xandersalarie.com/",
    "https://minecraft.xandersalarie.com/status",
  ];
  late WebViewController _controller;

  @override
  void initState() {
    super.initState();
  }

  void _onItemTapped(int index) {
    setState(() {
      _selectedIndex = index;
    });
    _controller.loadUrl(_urls[index]);
  }

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      debugShowCheckedModeBanner: false,
      home: Scaffold(
        body: SafeArea(
          child: WebView(
            initialUrl: _urls[_selectedIndex],
            javascriptMode: JavascriptMode.unrestricted,
            onWebViewCreated: (WebViewController webViewController) {
              _controller = webViewController;
            },
          ),
        ),
        bottomNavigationBar: BottomNavigationBar(
          items: const <BottomNavigationBarItem>[
            BottomNavigationBarItem(
              icon: Icon(Icons.home),
              label: 'Home',
            ),
            BottomNavigationBarItem(
              icon: Icon(Icons.stacked_bar_chart_outlined),
              label: 'Status',
            ),
          ],
          currentIndex: _selectedIndex,
          selectedItemColor: Colors.amber[800],
          onTap: _onItemTapped,
        ),
      ),
    );
  }
}

я попробовал реализовать это, и это сработало! я также заменил текущую нижнюю панель навигации на панель Gnav с pub.dev

RavenGaming 09.05.2024 19:51

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

Похожие вопросы

ПроизводноеStateOf не отвечает. Помогите мне понять, почему
Средства за встроенные приложения Google Play всегда возвращаются через 3 дня в Xamarin.Android/.NET 8
Как я могу сохранить настройки в Jetpack Compose, используя хранилище данных настроек?
Как удалить все записи в базе данных и полностью ее инициализировать, включая первичные ключи, при переустановке приложения в Android Room?
Исключение Apache SSHD из-за отсутствия определенного домашнего каталога пользователя
Использование сериализации Kotlin Kotlinx с дженериками
Получение API возвращает массив массивов вместо массива объектов с использованием Retrofit и Gson
Временная блокировка при использовании диспетчера учетных данных для входа в Google
Циклическая зависимость между следующими задачами после обновления плагина Gradle и плагина Firebase Crashlytics
Ошибка при открытии складного avd: для устройства Pixel_fold требуется функция складывания, но образ системы не поддерживает