Flutter 按钮应该加载新的 webview url

Posted

技术标签:

【中文标题】Flutter 按钮应该加载新的 webview url【英文标题】:Flutter button should load new webview url 【发布时间】:2018-10-01 15:05:14 【问题描述】:

这可能是一个比较简单的问题,但是我是 Flutter 新手,今天需要实现一下。

我有一个看起来像这样的 Flutter 应用...

有一个 Flutter BottomNavigationBar 和一个 Flutter Webview_Plugin

我需要的只是在按下 Home 或 Language 按钮时加载一个新的 url。但我无法完全弄清楚 Flutter 范式。

我当前的代码,如果有帮助的话:

import 'dart:async';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_webview_plugin/flutter_webview_plugin.dart';
import 'package:flutter_webview_plugin_example/home.dart';
import 'package:flutter_webview_plugin_example/settings.dart';

const kandroidUserAgent =
    'Mozilla/5.0 (Linux; Android 6.0; Nexus 5 Build/MRA58N) AppleWebKit/537.36 (Khtml, like Gecko) Chrome/62.0.3202.94 Mobile Safari/537.36';

String selectedUrl = 'http://google.com';

void main() 
  runApp(new MyApp());


class MyApp extends StatelessWidget 
  @override
  Widget build(BuildContext context) 
    return new MaterialApp(
      title: 'MyApp',
      theme: new ThemeData(
        primarySwatch: Colors.blue,
      ),
      routes: 
        '/': (_) => const MyHomePage(title: 'MyApp'),
        '/widget': (_) => new WebviewScaffold(
              url: selectedUrl,
              appBar: new AppBar(
                title: const Text('Widget webview'),
              ),
              withZoom: true,
              withLocalStorage: true,
            )
      ,
    );
  


class MyHomePage extends StatefulWidget 
  const MyHomePage(Key key, this.title) : super(key: key);

  final String title;

  @override
  _MyHomePageState createState() => new _MyHomePageState();


class _MyHomePageState extends State<MyHomePage> 
  // Instance of WebView plugin
  final flutterWebviewPlugin = new FlutterWebviewPlugin();

  // On destroy stream
  StreamSubscription _onDestroy;

  // On urlChanged stream
  StreamSubscription<String> _onUrlChanged;

  // On urlChanged stream
  StreamSubscription<WebViewStateChanged> _onStateChanged;

  StreamSubscription<WebViewHttpError> _onHttpError;

  StreamSubscription<double> _onScrollYChanged;

  StreamSubscription<double> _onScrollXChanged;

  final _urlCtrl = new TextEditingController(text: selectedUrl);

  final _codeCtrl =
      new TextEditingController(text: 'window.navigator.userAgent');

  final _scaffoldKey = new GlobalKey<ScaffoldState>();

  final _history = [];

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

    flutterWebviewPlugin.close();

    SystemChrome.setEnabledSystemUIOverlays([SystemUiOverlay.bottom]);

    _urlCtrl.addListener(() 
      selectedUrl = _urlCtrl.text;
    );

    // Add a listener to on destroy WebView, so you can make came actions.
    _onDestroy = flutterWebviewPlugin.onDestroy.listen((_) 
      if (mounted) 
        // Actions like show a info toast.
        _scaffoldKey.currentState.showSnackBar(
            const SnackBar(content: const Text('Webview Destroyed')));
      
    );

    // Add a listener to on url changed
    _onUrlChanged = flutterWebviewPlugin.onUrlChanged.listen((String url) 
      if (mounted) 
        setState(() 
          _history.add('onUrlChanged: $url');
        );
      
    );

    _onScrollYChanged =
        flutterWebviewPlugin.onScrollYChanged.listen((double y) 
      if (mounted) 
        setState(() 
          _history.add("Scroll in Y Direction: $y");
        );
      
    );

    _onScrollXChanged =
        flutterWebviewPlugin.onScrollXChanged.listen((double x) 
      if (mounted) 
        setState(() 
          _history.add("Scroll in X Direction: $x");
        );
      
    );

    _onStateChanged =
        flutterWebviewPlugin.onStateChanged.listen((WebViewStateChanged state) 
      if (mounted) 
        setState(() 
          _history.add('onStateChanged: $state.type $state.url');
        );
      
    );

    _onHttpError =
        flutterWebviewPlugin.onHttpError.listen((WebViewHttpError error) 
      if (mounted) 
        setState(() 
          _history.add('onHttpError: $error.code $error.url');
        );
      
    );
  

  @override
  void dispose() 
    // Every listener should be canceled, the same should be done with this stream.
    _onDestroy.cancel();
    _onUrlChanged.cancel();
    _onStateChanged.cancel();
    _onHttpError.cancel();
    _onScrollXChanged.cancel();
    _onScrollYChanged.cancel();

    flutterWebviewPlugin.dispose();

    super.dispose();
  

  @override
  Widget build(BuildContext context) 
    BottomNavigationBar btm = new BottomNavigationBar(
      items: [
        new BottomNavigationBarItem(
            icon: new Icon(
              Icons.home,
              color: const Color(0xFFFFFFFF),
            ),
            title: new Text(
              "Home",
              style: new TextStyle(
                color: const Color(0xFFFFFFFF),
              ),
            )),
        new BottomNavigationBarItem(
            icon: new Icon(
              Icons.settings,
              color: const Color(0xFFFFFFFF),
            ),
            title: new Text(
              "Language",
              style: new TextStyle(
                color: const Color(0xFFFFFFFF),
              ),
            )),
      ],
//      onTap: changeURL()
    );

    flutterWebviewPlugin.launch(selectedUrl,
    rect: new Rect.fromLTWH(
    0.0, 0.0,
    MediaQuery.of(context).size.width, MediaQuery.of(context).size.height - 55),
    userAgent: kAndroidUserAgent);

    return new Scaffold(
      appBar: new AppBar(
        title: new Text(
          widget.title,
          style: new TextStyle(color: const Color(0xFFFFFFFF)),
        ),
      ),
      bottomNavigationBar: new Theme(
        data: Theme.of(context).copyWith(
          // sets the background color of the `BottomNavigationBar`
          canvasColor: const Color(0xFF167F67),
        ), // sets the inactive color of the `BottomNavigationBar`
        child: btm
      ),
    );
  

【问题讨论】:

【参考方案1】:

所以看起来只需要下面的 onTap 之类的东西......

@override
Widget build(BuildContext context) 
  BottomNavigationBar btm = new BottomNavigationBar(
    items: [
      new BottomNavigationBarItem(
          icon: new Icon(
            Icons.home,
            color: const Color(0xFFFFFFFF),
          ),
          title: new Text(
            "Home",
            style: new TextStyle(
              color: const Color(0xFFFFFFFF),
            ),
          )),
      new BottomNavigationBarItem(
          icon: new Icon(
            Icons.settings,
            color: const Color(0xFFFFFFFF),
          ),
          title: new Text(
            "Language",
            style: new TextStyle(
              color: const Color(0xFFFFFFFF),
            ),
          )),
    ],
    onTap: (int index) 
      flutterWebviewPlugin.close();
      flutterWebviewPlugin.launch('http://google.com',
          rect: new Rect.fromLTWH(
              0.0, 0.0,
              MediaQuery.of(context).size.width, MediaQuery.of(context).size.height - 55),
          userAgent: kAndroidUserAgent);
    ,
  );

回想起来很简单,但很难做到恰到好处

【讨论】:

以上是关于Flutter 按钮应该加载新的 webview url的主要内容,如果未能解决你的问题,请参考以下文章

为啥 Flutter WebView 不加载页面?

使用flutter webview作为主页并按下后退按钮关闭应用程序

应该如何调用 Override Url

Flutter ------- WebView加载网页

Flutter Spinkit 进度指示器

Flutter:从 WebView 加载 IFrame