美文网首页
Flutter-语法总结

Flutter-语法总结

作者: AngeloD | 来源:发表于2022-02-07 16:27 被阅读0次

    Flutter-语法总结

    1. 获取屏幕宽高:

      import 'dart:ui';
      
      // 手机屏幕的大小(逻辑分辨率)
      final width = MediaQuery.of(context).size.width;
      final height = MediaQuery.of(context).size.height;
      
      // 手机的物理分辨率
      final physicalWidth = window.physicalSize.width;
      final physicalHeight = window.physicalSize.height;
      // 分辨率
      var resolution = physicalWidth * physicalHeight;
      
      // 获取dpr
      final dpr = window.devicePixelRatio;
      
      // 屏幕的物理宽度、高度
      final width = physicalWidth / dpr;
      final height = physicalHeight / dpr;
      print('屏幕宽高: $width * $height');
      
      // 状态栏的高度
      final statusHeight = window.padding.top / dpr;
      print('状态栏的高度: $statusHeight');
      
      // 不同手机尺寸的屏幕的状态栏高度不一致,需要获取状态栏高度
      // 设置上边距:
      MediaQueryData.fromWindow(window).padding.top
      
      // 使用时候设置上边距:
      return Scaffold(
          body:Container(
              padding: EdgeInsets.only(top: MediaQueryData.fromWindow(window).padding.top),
              child: Test("你瞅啥"),
          )
      );
      
    2. 配置WebView

      Widget _logicMapView() {
      
          initViewsAnchor();
      
          return Visibility(
            visible: state.logicMapUrl.length > 0,
            child: SizedBox(
              width: MediaQuery.of(context).size.width,
              // height: 400,
              height: (MediaQuery.of(context).size.height - _goodsInfoHeightOffsetY - 20),
              child: Column(
                children: [
                  Expanded(
                    child: WebView(
                      initialUrl: state.logicMapUrl,  //需要打开的url
                      //是否支持js 默认是不支持的,
                      javascriptMode: JavascriptMode.unrestricted,
                      onWebViewCreated: (WebViewController controller) {
                        //页面加载的时候可以获取到controller可以用来reload等操作
                        state.logicMapWebController = controller;
                      },
                      //加载js方法到页面内,js通过此来调用flutter的方法
                      javascriptChannels: {
                        JavascriptChannel(name: "Resize", onMessageReceived: (JavascriptMessage message) {
                          setState(() {
                            state.logicMapHeight = double.parse(message.message);
                          });
                        }),
                      },
                      onPageStarted: (String url) {
                      },
                      onPageFinished: (String url) {
                        print("你瞅啥:onPageFinished:$state.logicMapWebController");
                        //调用JS得到实际高度
                        state.logicMapWebController.evaluateJavascript("document.documentElement.scrollHeight;").then((result){
                          setState(() {
                            if (state.logicMapHeight != double.parse(result)) {
                              state.logicMapHeight = double.parse(result);
                            }
                            // state.logicMapHeight = 500;
                          });
                        });
                        state.logicMapWebController.evaluateJavascript("document.documentElement.body.scrollHeight;").then((result){
                          print("你瞅啥:evaluateJavascript:body:scrollHeight:");
                          setState(() {
                            print("你瞅啥:setState:scrollHeight:body:result:$result");
                            if (state.logicMapHeight != double.parse(result)) {
                              state.logicMapHeight = double.parse(result);
                            }
                            // state.logicMapHeight = 500;
                          });
                        });
                      },
                      //拦截页面url
                      navigationDelegate: (NavigationRequest request) {
                        if (request.url.startsWith('alipays:') ||
                            request.url.startsWith('weixin:')) {
                          _openPay(context, request.url);
                          return NavigationDecision.prevent;
                        }
                        return NavigationDecision.navigate;
                      },
                    ),
                  ),
                ],
              ),
            ),
          );
      }
      
    3. WebView高度计算:

      flutter一个界面内多个组件,如ListView包裹着一个Text和一个webview,此时,必须计算出webview的高度,才可正常显示,否则程序会因webview没给出高度而layout崩溃。

      以下为解决方案:

      1. 使用SizedBox进行包裹webview:
      Widget buildWebView() {
      return SizedBox(
        width: _webWidth,
        height: _webHeight,
        child: WebView(
          zoomEnabled: true,
          initialUrl: _webViewUrl,
          javascriptMode: JavascriptMode.unrestricted,
          onWebViewCreated: (controller) {
            _webController = controller;
            controller.loadUrl(Uri.dataFromString(_webViewUrl,
                mimeType: 'text/html', encoding: Encoding.getByName('utf-8'))
                .toString());
          },
          onPageFinished: (url) async {
            ///获取webView原始高度
            var originalHeight = await _webController!.runJavascriptReturningResult("document.documentElement.clientHeight;");
            _originalHeight = double.parse(originalHeight);
      
            ///获取webView原始宽度
            var originalWidth = await _webController!.runJavascriptReturningResult("document.documentElement.clientWidth;");
            _originalWidth = double.parse(originalWidth);
      
            ///计算等比例 图片高度
            /// W1/H1 = W2/H2;
            /// H2 = H1 * W2 / W1;
            setState(() {
              _webHeight = _originalHeight! * _webWidth / _originalWidth!;
            });
      
          },
        ),
      );
      

    }

    ```
    
    2. 获取webview内html原始宽度和高度,已知屏幕宽度,求出需要的比例高度
        
        公式:
        
        ```
        final double _webWidth = WYSizeFit.screenWidth!;// webview 已知屏幕宽度
      double _webHeight = 100;// 求 webview高度
      double? _originalWidth;//原宽度
      double? _originalHeight;//原高度
      
        
        ```
        
        ```
        onPageFinished: (url) async {
          ///获取webView原始高度
          var originalHeight = await _webController!.runJavascriptReturningResult("document.documentElement.clientHeight;");
          _originalHeight = double.parse(originalHeight);
        
          ///获取webView原始宽度
          var originalWidth = await _webController!.runJavascriptReturningResult("document.documentElement.clientWidth;");
          _originalWidth = double.parse(originalWidth);
        
          ///计算等比例 图片高度
          /// W1/H1 = W2/H2;
          /// H2 = H1 * W2 / W1;
          setState(() {
            _webHeight = _originalHeight! * _webWidth / _originalWidth!;
          });
        
        }
        ```
        
    完整代码:
    
    ```
    import 'dart:convert';
    
    import 'package:flutter/material.dart';
    import 'package:jd_shop/core/models/home/w_y_home_model.dart';
    import 'package:jd_shop/utils/network/wy_network.dart';
    import 'package:jd_shop/utils/network/wy_network_const.dart';
    import 'package:jd_shop/utils/screen_size/wy_screen_size.dart';
    import 'package:jd_shop/utils/wy_log/wylog.dart';
    import 'package:webview_flutter/webview_flutter.dart';
    
    class WYHomeDetailsHistoryView extends StatefulWidget {
    
      final List1 model;
    
      const WYHomeDetailsHistoryView(this.model,{Key? key}) : super(key: key);
    
      @override
      _WYHomeDetailsHistoryViewState createState() => _WYHomeDetailsHistoryViewState();
    }
    
    class _WYHomeDetailsHistoryViewState extends State<WYHomeDetailsHistoryView> with AutomaticKeepAliveClientMixin {
    
      @override
      // TODO: implement wantKeepAlive
      bool get wantKeepAlive => true;
      String _webViewUrl = "";
    
      final double _webWidth = WYSizeFit.screenWidth!;// webview 已知屏幕宽度
      double _webHeight = 100;// 求 webview高度
      double? _originalWidth;//原宽度
      double? _originalHeight;//原高度
    
      WebViewController? _webController;
    
      @override
      void initState() {
        super.initState();
    
        Map<String,dynamic> params = {
          "ProductID" : widget.model.productID,
          "devtype" : "3",
        };
        WYHttpRequest.request(WYNetWorkUrl.GetDetailByProID,params: params,loadingStr: "加载中...").then((value){
          setState(() {
            _webViewUrl = value["Data"]["info"]["Bewrite"];
          });
        });
      }
    
      @override
      Widget build(BuildContext context) {
        super.build(context);
    
        if(_webViewUrl.isEmpty){
          return Text("");
        }
    
        return ListView(
          shrinkWrap: true,
          children: [
            Container(
              child: Text("我是顶部文字"),
              color: Colors.orange,
              width: double.infinity,
              height: 100,
            ),
            buildWebView(),
          ],
        );
      }
    
      Widget buildWebView() {
        return SizedBox(
          width: _webWidth,
          height: _webHeight,
          child: WebView(
            zoomEnabled: true,
            initialUrl: _webViewUrl,
            javascriptMode: JavascriptMode.unrestricted,
            onWebViewCreated: (controller) {
              _webController = controller;
              controller.loadUrl(Uri.dataFromString(_webViewUrl,
                  mimeType: 'text/html', encoding: Encoding.getByName('utf-8'))
                  .toString());
            },
            onPageFinished: (url) async {
              ///获取webView原始高度
              var originalHeight = await _webController!.runJavascriptReturningResult("document.documentElement.clientHeight;");
              _originalHeight = double.parse(originalHeight);
    
              ///获取webView原始宽度
              var originalWidth = await _webController!.runJavascriptReturningResult("document.documentElement.clientWidth;");
              _originalWidth = double.parse(originalWidth);
    
              ///计算等比例 图片高度
              /// W1/H1 = W2/H2;
              /// H2 = H1 * W2 / W1;
              setState(() {
                _webHeight = _originalHeight! * _webWidth / _originalWidth!;
              });
    
            },
          ),
        );
      }
    
      @override
      void dispose() {
        //为了避免内存泄露,需要调用
        super.dispose();
      }
    
    }
        
    ```
    
    1. 获取某个Widget的宽高、位置:

      class HomePageState extends State<HomePage>
      with SingleTickerProviderStateMixin {
      
      
        // 全局定义需要获取的组件的标识key
        GlobalKey _anchorKey = GlobalKey();
        // 需要获取的控件的y
        double _goodsInfoHeightOffsetY = 0.0;
        
        // 获取标识key的位置信息
        double initOffsetY(GlobalKey key) {
          if (key.currentContext == null) {
            return null;
          }
          
          // 获取标识key的相关信息
          RenderBox renderBox = key.currentContext.findRenderObject();
      
          // 获取标识key的位置:offset.dx , offset.dy 就是控件的左上角坐标
          var offset = renderBox.localToGlobal(Offset.zero);
          
          // 获取标识key的位置:offset.dx , offset.dy 就是控件的左下角坐标
          var offset1 = renderBox.localToGlobal(Offset(0.0, renderBox.size.height));
          
          // 获取标识key的大小
          var size = renderBox.size;
      
          // return renderBox.localToGlobal(Offset.zero).dy;
          return renderBox.localToGlobal(Offset(0.0, renderBox.size.height)).dy;
        }
        
        // 获取标识key的回调信息
        void initViewsAnchor() {
          WidgetsBinding.instance.addPostFrameCallback((timeStamp) {
            _goodsInfoHeightOffsetY = initOffsetY(_anchorKey);
          });
        }
      
        @override
        Widget build(BuildContext context) {
          var size = MediaQuery.of(context).size;
          var width = size.width;
          var height = size.height;
          return Scaffold(
            appBar: AppBar(
              title: Text('Width & Height'),
            ),
            body: Center(
              child: Container(
                
                
                // 需要获取位置的组件,添加key
                key: _anchorKey,
                
                
                color: Colors.redAccent,
                width: width / 2,
                height: height / 2,
              ),
            ),
          );
        }
        
        Widget _logicMapView() {
        
          // 需要根据某个组件确定自己位置时,调用该自定义方法,获取上面组件的位置
          initViewsAnchor();
      
          return Visibility(
            visible: state.logicMapUrl.length > 0,
            child: SizedBox(
              width: MediaQuery.of(context).size.width,
              
              
              // 通过获取到的上面组件的位置,来确定新组件的大小
              height: (MediaQuery.of(context).size.height - _goodsInfoHeightOffsetY - 20),
              
              
              child: 。。。。。,
            ),
          );
        }
      }
      
      
    2. 地址选择器:

      
      #  flutter_jd_address_selector:
      #    git:
      #      url: https://github.com/shenhuaxiyuan/flutter_jd_address_selector
      
      
      

    相关文章

      网友评论

          本文标题:Flutter-语法总结

          本文链接:https://www.haomeiwen.com/subject/ahumkrtx.html