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.
        );
      }
    }
  • 相关阅读:
    CAP 理论笔记
    介绍 GOMEZ
    CDN资料下载(1) 20091223
    About网宿CDN
    [笔记] Darwin Streaming server 的 Task 类
    手把手教你写“隐藏图标托盘程序”
    WIN7下使用OpenSCManger和OpenService函数的注意
    oracle按月、日、时分组查询数据,为空的数据补零
    搜索引擎学习
    JSONP与JSON
  • 原文地址:https://www.cnblogs.com/hbolin/p/11462332.html
Copyright © 2011-2022 走看看