Скриншоты / Скриншоты компонентов Flutter

Flutter

Продолжайте обновлять серию Flutter. В этой статье рассказывается, как делать скриншоты во Flutter. Во Flutter все является компонентом, не только размытие по Гауссу — это слой компонентов, но и скриншоты — это слой компонентов, поэтому скриншоты и скриншоты компонентов на самом деле то же самое. Хотя вложенный пользовательский интерфейс Flutter очень громоздкий, но когда вы к нему привыкнете, вы почувствуете, что структура очень понятна, и вам не нужно беспокоиться о путанице кодов, связанных с макетом. карту распознавания, и вы сможете быстро понять других, не листая код.Письменная раскладка.
На этот раз используется компонент RepaintBoundary, рендеринг:

效果展示

Создайте проект на флаттере

По соглашению создайте простой проект Flutter и уберите ненужный код в main.dart для демонстрации:

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: MyHomePage(title: 'Flutter 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> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(widget.title),
      ),
      body: Column(),
    );
  }
}

Это пустой интерфейс с заголовком.

написать простую сцену

Для удобства демонстрации добавьте в этот интерфейс изображение в формате gif.Конечно, вы также можете использовать обычные изображения или видео:

class _MyHomePageState extends State<MyHomePage> {
  Future<Uint8List> _capturePng() async {
    //TODO 进行截图
  }
  
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(widget.title),
      ),
      body: Column(
        children: <Widget>[
          Image.network(
            "http://qiniu.nightfarmer.top/test.gif",
            width: 300,
            height: 300,
          ),
          FlatButton(
            onPressed: () {
              this._capturePng();
            },
            child: Text("全屏截图"),
          ),
        ],
      ),
    );
  }
}

После добавления изображения я, кстати, добавил компонент FlatButton, и нажмите эту кнопку, чтобы запустить логику снимка экрана.
Конечно пока это просто макет интерфейса, ничего нового не используется.

Как сделать снимок экрана

Как упоминалось ранее, в этой статье будет использоватьсяRepaintBoundaryКомпонент, а затем поместите его на внешний слой компонента, который вы хотите сделать скриншоты.Если вы хотите сделать полный экран, вы можете поместить его на самый внешний слой.Привычка письма Flutter хороша.
В то же время определите ключ для работы с этим компонентом

class _MyHomePageState extends State<MyHomePage> {
  GlobalKey rootWidgetKey = GlobalKey();
  ...

  @override
  Widget build(BuildContext context) {
    return RepaintBoundary(
      key: rootWidgetKey,
      child: Scaffold(
        appBar: AppBar(
          title: Text(widget.title),
        ),
        body: Column(
          .....
        ),
      ),
    );
  }
}

Вы можете получить ссылку на RenderRepaintBoundary через rootWidgetKey и зайти, чтобы получить скриншот внутренних компонентов:

class _MyHomePageState extends State<MyHomePage> {
  GlobalKey rootWidgetKey = GlobalKey();

  Future<Uint8List> _capturePng() async {
    try {
      RenderRepaintBoundary boundary =
          rootWidgetKey.currentContext.findRenderObject();
      var image = await boundary.toImage(pixelRatio: 3.0);
      ByteData byteData = await image.toByteData(format: ImageByteFormat.png);
      Uint8List pngBytes = byteData.buffer.asUint8List();
      return pngBytes;//这个对象就是图片数据
    } catch (e) {
      print(e);
    }
    return null;
  }
  ...
}

С помощью приведенной выше последовательности вызовов методов получаются данные изображения типа Unit8List.

Дисплей скриншоты

Отображение данных изображения типа Unit8List также очень просто.Изображение загружается из памяти через метод Image.memory.Полный код состояния прилагается ниже:

class _MyHomePageState extends State<MyHomePage> {
  GlobalKey rootWidgetKey = GlobalKey();

  List<Uint8List> images = List();

  _capturePng() async {
    try {
      RenderRepaintBoundary boundary =
          rootWidgetKey.currentContext.findRenderObject();
      var image = await boundary.toImage(pixelRatio: 3.0);
      ByteData byteData = await image.toByteData(format: ImageByteFormat.png);
      Uint8List pngBytes = byteData.buffer.asUint8List();
      images.add(pngBytes);
      setState(() {});
      return pngBytes;
    } catch (e) {
      print(e);
    }
    return null;
  }

  @override
  Widget build(BuildContext context) {
    return RepaintBoundary(
      key: rootWidgetKey,
      child: Scaffold(
        appBar: AppBar(
          title: Text(widget.title),
        ),
        body: Column(
          children: <Widget>[
            Image.network(
              "http://qiniu.nightfarmer.top/test.gif",
              width: 300,
              height: 300,
            ),
            FlatButton(
              onPressed: () {
                this._capturePng();
              },
              child: Text("全屏截图"),
            ),
            Expanded(
              child: ListView.builder(
                itemBuilder: (context, index) {
                  return Image.memory(
                    images[index],
                    fit: BoxFit.cover,
                  );
                },
                itemCount: images.length,
                scrollDirection: Axis.horizontal,
              ),
            )
          ],
        ),
      ),
    );
  }
}

Сделанный.


Больше галантерейных товаров перемещается в мой личный блогwww.nightfarmer.top/