zoukankan      html  css  js  c++  java
  • Flutter Widget截图

    Flutter中截图的主要类是RepaintBoundary。

    废话不多说,直接上代码:

    import 'dart:typed_data';
    import 'dart:ui' as ui;
    import 'package:flutter/material.dart';
    import 'package:flutter/rendering.dart';
    
    class WidgetShot extends StatefulWidget {
      final Widget child;
      final ShotController controller;
    
      WidgetShot({@required this.child, this.controller});
    
      @override
      _WidgetShotState createState() => _WidgetShotState();
    }
    
    class _WidgetShotState extends State<WidgetShot> {
      GlobalKey<_OverRepaintBoundaryState> globalKey = GlobalKey();
    
      @override
      void initState() {
        super.initState();
        if (widget.controller != null) {
          widget.controller.setGlobalKey(globalKey);
        }
      }
    
      @override
      Widget build(BuildContext context) {
        return SingleChildScrollView(
          scrollDirection: Axis.vertical,
          child: SingleChildScrollView(
            scrollDirection: Axis.horizontal,
            child: _OverRepaintBoundary(
              key: globalKey,
              child: RepaintBoundary(
                child: widget.child,
              ),
            ),
          ),
        );
      }
    }
    
    class _OverRepaintBoundary extends StatefulWidget {
      final Widget child;
    
      const _OverRepaintBoundary({Key key, this.child}) : super(key: key);
    
      @override
      _OverRepaintBoundaryState createState() => _OverRepaintBoundaryState();
    }
    
    class _OverRepaintBoundaryState extends State<_OverRepaintBoundary> {
      @override
      Widget build(BuildContext context) {
        return widget.child;
      }
    }
    
    class ShotController {
      GlobalKey<_OverRepaintBoundaryState> globalKey;
    
      Future<Uint8List> makeImageUint8List() async {
        RenderRepaintBoundary boundary = globalKey.currentContext.findRenderObject();
        // 这个可以获取当前设备的像素比
        var dpr = ui.window.devicePixelRatio;
        ui.Image image = await boundary.toImage(pixelRatio: dpr);
        ByteData byteData = await image.toByteData(format: ui.ImageByteFormat.png);
        Uint8List pngBytes = byteData.buffer.asUint8List();
        return pngBytes;
      }
    
      setGlobalKey(GlobalKey<_OverRepaintBoundaryState> globalKey) {
        this.globalKey = globalKey;
      }
    }

    测试使用:

    import 'dart:typed_data';
    
    import 'package:flutter/material.dart';
    import 'package:flutter_app/widget_shot.dart';
    
    void main() => runApp(MyApp());
    
    class MyApp extends StatelessWidget {
      // This widget is the root of your application.
      @override
      Widget build(BuildContext context) {
        return MaterialApp(
          title: 'Flutter Demo',
          theme: ThemeData(
            primarySwatch: Colors.blue,
          ),
          home: MyHomePage(title: 'widget shot demo'),
        );
      }
    }
    
    class MyHomePage extends StatefulWidget {
      MyHomePage({Key key, this.title}) : super(key: key);
    
      final String title;
    
      @override
      _MyHomePageState createState() => _MyHomePageState();
    }
    
    class _MyHomePageState extends State<MyHomePage> {
      // 关键是创建Controller
      ShotController shotController = new ShotController();
    
      int _counter = 0;
    
      void _incrementCounter() async {
        setState(() {
          _counter++;
        });
    
        // 将widget生成Uint8List传递给Image即可
        Uint8List pngBytes = await shotController.makeImageUint8List();
        
        Navigator.push(context, new MaterialPageRoute(builder: (_) {
          return Scaffold(
            appBar: AppBar(
              title: Text('shot widget'),
            ),
            body: Image.memory(pngBytes),
          );
        }));
      }
    
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          appBar: AppBar(
            title: Text(widget.title),
          ),
          body: WidgetShot(
            controller: shotController,
            child: Center(
              child: Column(
                mainAxisAlignment: MainAxisAlignment.center,
                children: <Widget>[
                  Text(
                    'You have pushed the button this many times:',
                  ),
                  Offstage(
                    offstage: true,
                    child: Text('offstage demo'),
                  ),
                  Text(
                    '$_counter',
                    style: Theme.of(context).textTheme.display1,
                  ),
                ],
              ),
            ),
          ),
          floatingActionButton: FloatingActionButton(
            onPressed: _incrementCounter,
            tooltip: 'Increment',
            child: Icon(Icons.add),
          ), // This trailing comma makes auto-formatting nicer for build methods.
        );
      }
    }
  • 相关阅读:
    oracle的分析函数over 及开窗函数
    ASP.NET中分布式事务的使用
    后台实现显示欢迎用户登陆的方法
    AjaxHelper的get和post请求的封装类
    登陆权限验证Session和Cookie用法及BasePage类使用
    四个常用.NET的SqlHelper的方法
    ASP.NET在实际开发中验证码的用法
    SQL Server事务的存储过程
    利用JQuery实现全选和反选的几种方法
    JS中表格的全选和删除要注意的问题
  • 原文地址:https://www.cnblogs.com/hbolin/p/11462332.html
Copyright © 2011-2022 走看看