flutter WebView

dart 复制代码
import 'dart:convert';

import 'package:constant/constant.dart';
import 'package:generated/l10n.dart';
import 'package:http/DioManager.dart';
import 'package:http/api/info_express_api.dart';
import 'package:jade/configs/CommonConfig.dart';
import 'package:jade/configs/PathConfig.dart';
import 'package:jade/experienceStation/ExperienceStation.dart';
import 'package:jade/homePage/promotion/promotionPost/PromotionPostDetail.dart';
import 'package:jade/homePage/wantHave/WantPostDetail.dart';
import 'package:jade/utils/JadeColors.dart';
import 'package:jade/utils/LocationUtil.dart';
import 'package:jade/utils/Utils.dart';
import 'package:main.dart';
import 'package:pages/amap/view/amap_associate_list_page.dart';
import 'package:pages/cinema/list/cinema_select_business_page.dart';
import 'package:pages/goods/goods_detail.dart';
import 'package:pages/info_express/info_express_detail_page.dart';
import 'package:pages/life/life_shop_detail.dart';
import 'package:pages/my/windowPage.dart';
import 'package:pages/user_share/view/user_share_article_detail_page.dart';
import 'package:pages/want/want_detail/view.dart';
import 'package:util/navigator_util.dart';
import 'package:util/permission_util.dart';
import 'package:flutter/material.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
import 'package:get/get.dart';
import 'package:permission_handler/permission_handler.dart';
import 'package:webview_flutter/webview_flutter.dart';
/*
* 天地图h5网页-首页
* */
class MapWebView extends StatefulWidget{

  final String itemId; //帖子id
  final int itemType; //项目类型 1-商品,2-生活服务,3-影院广告,4-发帖推荐,5-促销速递,7-窗口,28-体验站
  final int type; // 0我有我要,1其他
  final int wantType; // 0 我有 1 我要
  final int isDetail; // 0是否从详情页面进来
  const MapWebView({this.itemId,this.itemType,this.type,this.wantType,this.isDetail});

  @override
  State<StatefulWidget> createState() {
    // TODO: implement createState
    return _MapWebView();
  }
}

class _MapWebView extends State<MapWebView> with AutomaticKeepAliveClientMixin,WidgetsBindingObserver,RouteAware {

final RouteObserver<Route<dynamic>> routeObserver = RouteObserver();
  WebViewController _webViewController;
  double _processPercent = 0.00;
  var _initLatLng;
  bool _canGoBack;
  @override
  void initState(){
    // TODO: implement initState
    super.initState();
    WidgetsBinding.instance.addObserver(this);
    _initLocation();
  }

  @override
  void didChangeDependencies() {
    routeObserver.subscribe(this, ModalRoute.of(context)); //订阅
    super.didChangeDependencies();
  }

  @override
  void didChangeAppLifecycleState(AppLifecycleState state) {
    // TODO: implement didChangeAppLifecycleState
    super.didChangeAppLifecycleState(state);
    switch(state){
      case AppLifecycleState.inactive:
        print('======inactive');
        break;
        case AppLifecycleState.resumed:
        print('======resumed');
        _initLocation();
        break;
        case AppLifecycleState.paused:
        print('======paused');
        break;
        case AppLifecycleState.detached:
        print('======detached');
        break;
    }

  }



  @override
  void dispose() {
    routeObserver.unsubscribe(this); //取消订阅
    WidgetsBinding.instance.removeObserver(this);
    super.dispose();
  }
  @override
  void didPush() {
    // TODO: implement didPop
    super.didPush();
    print('========didPush');
  }

  @override
  void didPushNext() {
    // TODO: implement didPop
    super.didPushNext();
    print('========didPushNext');
  }

  @override
  void didPopNext() {
    // TODO: implement didPopNext
    super.didPopNext();
    print('========didPopNext');
  }

  @override
  void didPop() {
    // TODO: implement didPop
    super.didPop();
    print('========didPop');
  }


  @override
  Widget build(BuildContext context) {
    // TODO: implement build
    return Scaffold(
      //backgroundColor: Color(0xff06ca9f).withOpacity(0.1),
      body: _body()
    );
  }
 _goBack(){
    if(_canGoBack == null){
      return;
    }
    if(_canGoBack){
      _webViewController.goBack();
    }else{
      Navigator.pop(context);
    }
  }

  _body(){
    return Column(
      children: [
        Container(
          color: Colors.white,
          height: Utils().statusBarHeight(context),
        ),
        Expanded(
            child: Stack(
              alignment: Alignment.center,
              children: [
                _initLatLng==null?Container():WebView(
                  initialUrl:
                  '${Constant.mapBaseUrl}?lng=${_initLatLng['lng']}&lat=${_initLatLng['lat']}',
                  javascriptMode: JavascriptMode.unrestricted,
                  onWebViewCreated: (controller) {
                    _webViewController = controller;
                  },
                  onPageStarted: (url){
                    print('url=$url $_initLatLng');
                  },
                  onProgress: (process){
                    setState(() {
                      _processPercent = process / 100;
                    });
                  },
                  onPageFinished: (url) {
                  //加载完成后的url
                  print('_detailUrl= $_detailUrl');
                    _webViewController.canGoBack().then((value){
                      setState(() {
                        _canGoBack = value;
                      });
                    });
                  },
                  },
                  javascriptChannels: <JavascriptChannel>[
                    _postUpGo(),
                    _postDownGo(),
                    _experienceGo(),
                    _postGo(),
                    _positioningGo(),
                  ].toSet(),
                ),
                Offstage(
                  offstage: _processPercent == 1.0,
                  child: Image.asset(PathConfig.loadingGif,height: 80.w,)
                )
              ],
            )
        ),
        Offstage(
          child: LinearProgressIndicator(
              backgroundColor: JadeColors.lightGrey,
              color: Color(0xff06ca9f).withOpacity(0.2),
              value: _processPercent),
          offstage: _processPercent == 1.0
        )
      ],
    );
  }

  _postUpGo() {
    return JavascriptChannel(
        name: 'postUpGo',
        onMessageReceived: (JavascriptMessage message) {
          dynamic value = json.decode(message.message);
          print('value= $value');
          var itemType = value['itemType'];
          var itemId = value['itemId'];
          var type = value['type'];
          var wantType = value['wantType'];
          var cateId = value['cateId'];
          switch(itemType){
            case 1:
              //商品
              NavigatorUtil.push(GoodsDetail(
                goodsId: itemId,
              ));
              break;
            case 2:
              //生活服务
              NavigatorUtil.push(LifeShopDetail(
                int.parse(itemId),
              ));
              break;
            case 3:
              //影院广告
              NavigatorUtil.push(CinemaSelectBusinessPage(
                cinemaId: int.parse(itemId),
              ));
              break;
            case 4:
              //发帖推荐
              if(type == 0){
                /*Get.to(() => WantDetailPage(),
                    arguments: {
                      "id": int.parse(itemId),
                      "openComment": false,
                    });*/
                Get.to(() => WantPostDetail(), arguments: {
                  "id":int.parse(itemId),
                  "openComment": false,
                  'wantHaveType': cateId == 30?0:1
                });
              }else if(cateId == 34){
                NavigatorUtil.push(PromotionPostDetail(id: itemId));
              }else{
                NavigatorUtil.push(
                    UserShareArticleDetailPage(itemId, (value) {}, 1));
              }
              break;
            case 5:
              //促销速递
              DioManager.getInstance().getQuery(
                  InfoExpressApi.INFORMATION_EXPRESS + '/$itemId', null, (value) {
                if (value['code'] == 200) {
                  var data = value['data'];
                  Map<String, dynamic> item = {
                    "itemId": "$itemId",
                    "itemName": "${data['title']}",
                    "itemContent": "${data['content']}",
                    "itemPic": "${data['pic']}",
                    "itemType": 5, // 1 商品 , 2 影院 3 生活服务 4 视频 5 信息快递
                    "articleItemType": 1,
                    "articleType": 3,
                  };
                  NavigatorUtil.push(InfoExpressDetailPage(int.parse(itemId), item));
                }
              }, (err) {
                print('err $err');
              });
              break;
            case 7:
              //窗口
              NavigatorUtil.push(WindowPage(
                arguments: {
                  "userId": value['userId'],
                  "nickname": value['nickname'],
                  "avatar": value['avatar'],
                },
              ));
              break;
            case 28:
              //体验站
              NavigatorUtil.push(ExperienceStation(id: itemId));
              break;
          }
        });
  }

  _postDownGo(){
    return JavascriptChannel(
        name: 'postDownGo',
        onMessageReceived: (JavascriptMessage message) {
          dynamic value = json.decode(message.message);
          print('value= $value');
          var itemType = value['itemType'];
          var itemId = value['itemId'];
          var type = value['type'];
          var wantType = value['wantType'];
          switch(itemType){
            case 1:
            //商品
            case 2:
            //生活服务
            case 3:
            //影院广告
            case 4:
            //发帖推荐
            case 5:
            //促销速递
            case 7:
            //窗口
          //  case 28:
            //体验站
              NavigatorUtil.push(AMapAssociateListPage(
                itemId: itemId,
                type: itemType,
                isWant: type == 0
              ));
              break;
          }
        });
  }

  _experienceGo(){
    return JavascriptChannel(
        name: 'experienceGo',
        onMessageReceived: (JavascriptMessage message) {
          dynamic value = json.decode(message.message);
          print('value= $value');
          var itemId = value['itemId'];
          NavigatorUtil.push(ExperienceStation(id: itemId));
        });
  }

  _postGo() {
    return JavascriptChannel(
        name: 'postGo',
        onMessageReceived: (JavascriptMessage message) {
          dynamic value = json.decode(message.message);
          print('value= $value');
          var itemType = value['itemType'];
          var itemId = value['itemId'];
          var type = value['type'];
          var wantType = value['wantType'];
          switch(itemType){
            case 1:
            //商品
              if(itemId != null){
                NavigatorUtil.push(GoodsDetail(
                  goodsId: itemId,
                  fromMap: true,
                ));
              }

              break;
            case 2:
            //生活服务
              NavigatorUtil.push(LifeShopDetail(
                int.parse(itemId),
                fromMap: true,
              ));
              break;
            case 3:
            //影院广告
              NavigatorUtil.push(CinemaSelectBusinessPage(
                cinemaId: int.parse(itemId),
                fromMap: true,
              ));
              break;
            case 4:
            //发帖推荐
              if(type == 0){
                Get.to(() => WantDetailPage(),
                    arguments: {
                      "id": int.parse(itemId),
                      "openComment": false,
                    });
              }else{
                NavigatorUtil.push(
                    UserShareArticleDetailPage(itemId, (value) {}, 1));
              }
              break;
            case 5:
            //促销速递
              DioManager.getInstance().getQuery(
                  InfoExpressApi.INFORMATION_EXPRESS + '/$itemId', null, (value) {
                if (value['code'] == 200) {
                  var data = value['data'];
                  Map<String, dynamic> item = {
                    "itemId": "$itemId",
                    "itemName": "${data['title']}",
                    "itemContent": "${data['content']}",
                    "itemPic": "${data['pic']}",
                    "itemType": 5, // 1 商品 , 2 影院 3 生活服务 4 视频 5 信息快递
                    "articleItemType": 1,
                    "articleType": 3,
                  };
                  NavigatorUtil.push(InfoExpressDetailPage(int.parse(itemId), item));
                }
              }, (err) {
                print('err $err');
              });
              break;
            case 7:
            //窗口
              NavigatorUtil.push(WindowPage(
                arguments: {
                  "userId": value['userId'],
                  "nickname": value['nickname'],
                  "avatar": value['avatar'],
                },
              ));
              break;
            case 28:
            //体验站
              NavigatorUtil.push(ExperienceStation(id: itemId));
              break;
          }
        });
  }


  _positioningGo() {
    return JavascriptChannel(
        name: 'positioningGo',
        onMessageReceived: (JavascriptMessage message) async {
          var latLng = await LocationUtil().refreshAddressFromLatLng();
          if(_webViewController!=null && latLng!=null){
            _webViewController.runJavascript('handleCheckChangeEnd("$latLng")');
          }
        });
  }


  _initLocation() async {
    print('======定位权限');
    bool _currentAuth = await PermissionUtil.judgeLocationAuth();
    if(_currentAuth){
      _getLatLng();
    }else{
      bool _auth = await Utils.commonDialog(context,S.current.aTuiMapAuthTip+'\n3.拒绝后将无法正常使用地图功能'+'\n(开启权限后请重新启动软件)',disText: S.current.jujue,sureText: '去开启');
      if (_auth) {
         openAppSettings();
      }
    }
  }

  _getLatLng() async {
    _initLatLng = await LocationUtil().refreshAddressFromLatLng();
    setState(() {});
  }

  @override
  // TODO: implement wantKeepAlive
  bool get wantKeepAlive => true;
}
相关推荐
problc3 小时前
Flutter中文字体设置指南:打造个性化的应用体验
android·javascript·flutter
lqj_本人12 小时前
鸿蒙next选择 Flutter 开发跨平台应用的原因
flutter·华为·harmonyos
lqj_本人15 小时前
Flutter&鸿蒙next 状态管理框架对比分析
flutter·华为·harmonyos
起司锅仔19 小时前
Flutter启动流程(2)
flutter
hello world smile1 天前
最全的Flutter中pubspec.yaml及其yaml 语法的使用说明
android·前端·javascript·flutter·dart·yaml·pubspec.yaml
lqj_本人1 天前
Flutter 的 Widget 概述与常用 Widgets 与鸿蒙 Next 的对比
flutter·harmonyos
iFlyCai1 天前
极简实现酷炫动效:Flutter隐式动画指南第二篇之一些酷炫的隐式动画效果
flutter
lqj_本人1 天前
Flutter&鸿蒙next 中使用 MobX 进行状态管理
flutter·华为·harmonyos
lqj_本人1 天前
Flutter&鸿蒙next 中的 setState 使用场景与最佳实践
flutter·华为·harmonyos
hello world smile1 天前
Flutter常用命令整理
android·flutter·移动开发·android studio·安卓