【问题标题】:How to convert scrollable widget to image?如何将可滚动小部件转换为图像?
【发布时间】:2020-12-08 03:59:24
【问题描述】:

我有一个想要转换为图像的可滚动小部件,但是当我想要转换图像时只显示小部件的一部分。

在我上传的代码示例中,当按下浮动按钮时,它会将图像保存在图库中。 如您所见,它只保存了小部件的一部分。 关于如何保存整个小部件的任何建议?是否扩展并不重要。

import 'dart:io';

import 'dart:typed_data';

import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart';
import 'package:path_provider/path_provider.dart';

import 'dart:ui' as ui;

import 'package:image_save/image_save.dart';

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return new MaterialApp(
      title: 'Flutter prueba',
      theme: new ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: PruebaApp(),
    );
  }
}

class PruebaApp extends StatelessWidget {
  GlobalKey _globalKey = new GlobalKey();
  // Creamos la lista de nombres
  final List<String> nombres = [
    "Alberto",
    "Ricardo",
    "Francisco",
    "Gustavo",
    "Oscar",
    "Alejandro",
    "Nayla"
  ];

  PruebaApp({Key key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Flutter prueba'),
      ),
      //Utilizando el Scrollview.builder
      body: buildListView(_globalKey),
      floatingActionButton: botonTips(),
    );
  }

  RepaintBoundary buildListView(GlobalKey key) {
    return RepaintBoundary(
      key: key,
      child: ListView.builder(
        // tamaño de la lista
        itemCount: nombres.length,
        // Constructor de widget para cada elemento de la lista
        itemBuilder: (BuildContext context, int indice) {
          return Card(
            //le damos un color de la lista de primarios
            color: Colors.primaries[indice],
            //agregamos un contenedor de 100 de alto
            child: Container(
                height: 100,
                //Centramos con el Widget <a href="https://zimbronapps.com/flutter/center/">Center</a>
                child: Center(
                  //Agregamos el nombre con un Widget Text
                    child: Text(
                      nombres[indice],
                      //le damos estilo a cada texto
                      style: TextStyle(fontSize: 20, color: Colors.white),
                    ))),
          );
        },
      ),
    );
  }
  FloatingActionButton botonTips() {
    return FloatingActionButton(
      onPressed: () {
        capturePng();
      },
      child: Icon(Icons.lightbulb_outline),
      backgroundColor: Colors.redAccent,
    );
  }
  Future<void> capturePng() async {

    //var repaint = RepaintBoundary.wrap(buildListView(context), 0);
    //var boundary = RenderRepaintBoundary(child:repaint.createRenderObject(context));


    RenderRepaintBoundary boundary =  _globalKey.currentContext.findRenderObject();
    ui.Image image = await boundary.toImage();
    ByteData byteData = await image.toByteData(format: ui.ImageByteFormat.png);
    Uint8List pngBytes = byteData.buffer.asUint8List();
    print(pngBytes);
    File.fromRawPath(pngBytes);

    //Uint8List pngBytes=  await createImageFromWidget(SizedBox(height: MediaQuery.of(context).size.height,child: table,));
    final Directory directory = await getApplicationDocumentsDirectory();
    final File file = File('${directory.path}/file.png');
    await file.writeAsBytes(pngBytes);
    Directory dir = Platform.isAndroid
        ? await getExternalStorageDirectory()
        : await getApplicationDocumentsDirectory();
    if (!await file.exists()) {
      await file.create(recursive: true);
      file.writeAsStringSync("test for share documents file");
    }
    bool success = await ImageSave.saveImage(pngBytes, "gif", albumName: "demo");
    //ShareExtend.share(file.path, "file");
  }
}

【问题讨论】:

    标签: flutter dart


    【解决方案1】:

    有一个简单的方法 您需要将 SingleChildScrollView 小部件包装到 RepaintBoundary。只需用 SingleChildScrollView 包装您的 Scrollable 小部件(或他的父亲)

    SingleChildScrollView(
      child: RepaintBoundary(
         key: _globalKey
         child: Column() 
       )
    )
    

    【讨论】:

    • 谢谢!你的逻辑很好,但我遇到了一个小问题我收到了这个错误```'package:flutter/src/rendering/proxy_box.dart':断言失败:第3089行pos 12:'!debugNeedsPaint':不正确。 ``` 所以如果你关注同样的问题,去:stackoverflow.com/questions/57645037/…
    【解决方案2】:

    现在不可能。在 Flutter 的情况下,只绘制当前显示的屏幕,所以不绘制不可见的部分。如果要滚动捕获,则必须通过使用 CustomPainter 类的 Canvas 将其转换为位图来创建文件。

    网址链接:https://www.raywenderlich.com/7560981-drawing-custom-shapes-with-custompainter-in-flutter

    网址链接:How to save a Flutter canvas as a bitmap image?

    【讨论】:

      猜你喜欢
      • 2022-08-15
      • 1970-01-01
      • 2021-08-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-07-30
      • 1970-01-01
      • 2023-03-30
      相关资源
      最近更新 更多