Flutter之屏幕截图/组件截图

继续更新Flutter系列,本篇记录如何在Flutter中进行截图,在Flutter中万物皆组件,不但高斯模糊是套一层组件,截图也是套一层组件,所以屏幕截图和组件截图其实是一个意思。虽然Flutter的这种嵌套UI很繁琐,但是用习惯了反而会感觉结构很清晰,不用担心布局相关代码的混乱,在FlutterInspector识图下更是一目了然,可以在不翻阅代码的情况下快速理解别人写的布局。
本次用到的组件是RepaintBoundary,效果图:
效果展示

 

创建Flutter工程

依照惯例,创建一个简单的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的这种写法习惯就好。
同时定义一个Key用来操作这个组件

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(
          .....
        ),
      ),
    );
  }
}

通过rootWidgetKey可以拿到RenderRepaintBoundary的引用,进来拿到内部组件的截图:

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方法从内存中加载图片,下面附上完整的State代码:

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,
              ),
            )
          ],
        ),
      ),
    );
  }
}

  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 非常感谢您对我的提问。作为一个 AI 模型,我可以尽力回答您的问题,但我的能力有限,有些问题可能无法回答或者回答不够准确,请您谅解。 关于您提到的问题,我可以告诉您,Flutter 是一种流行的跨平台移动应用开发框架,它提供了许多常用的 UI 组件和工具,其中就包括 Text 组件。Text 组件可以用来显示文本,并支持一些常用的样式和格式,例如字体大小、颜色、粗细、对齐方式等等。 如果您需要在 Flutter 中使用 Text 组件,可以按照以下步骤操作: 1. 导入 Flutter 的 material 包:`import 'package:flutter/material.dart';` 2. 创建一个 Text 组件:`Text('Hello, world!')` 3. 在 Text 组件中添加一些样式和格式:`Text('Hello, world!', style: TextStyle(fontSize: 16.0, color: Colors.blue))` 当然,以上只是 Text 组件的简单使用方法,如果您需要更深入的了解,可以参考 Flutter 官方文档或者相关的教程和案例。 最后,再次感谢您的提问,希望我的回答能够帮助到您。如果您有其他问题,欢迎随时向我提出。 ### 回答2: Flutter中的Text组件用于显示文本内容。在使用Text组件时,您可以设置文本的样式、对齐方式、溢出方式等属性。 1. 首先,在您的Flutter项目中引入Text组件: ``` import 'package:flutter/material.dart'; ``` 2. 在您的Flutter页面中,使用Text组件来显示文本内容: ``` Text( '这是一个文本示例', style: TextStyle( fontSize: 20, // 设置字体大小为20 color: Colors.black, // 设置字体颜色为黑色 fontWeight: FontWeight.bold, // 设置字体加粗 ), ), ``` 3. 您还可以设置Text组件的对齐方式: ``` Text( '这是一个文本示例', textAlign: TextAlign.center, // 设置文本居中对齐 ), ``` 4. 对于长文本,您可以设置Text组件的溢出方式,以防止文字溢出: ``` Text( '这是一个长长长长长长长长长长长长长长长长长长长长长长长长长长长长长长长长长的文本示例', overflow: TextOverflow.ellipsis, // 使用省略号来表示溢出 ), ``` 5. 如果您想显示多行文本,可以使用Text组件的属性maxLines: ``` Text( '这是一个多行文本示例,这是第一行\n这是第二行', maxLines: 2, // 设置最大行数为2 ), ``` 以上是使用Text组件的一些常用属性和用法。您可以根据自己的需求来设置文本的样式、对齐方式和溢出方式,以实现您想要的效果。 ### 回答3: 使用Flutter的Text组件可以轻松地在应用程序中显示文本内容。以下是使用Text组件的步骤: 1. 导入对应的库文件:为了使用Text组件,首先要导入相应的库文件。在Flutter中,可以在Dart文件的开头添加以下语句导入所需的库: ``` import 'package:flutter/material.dart'; ``` 2. 创建Text小部件:要使用Text组件来显示文本,需要在应用程序的UI层次结构中创建一个相应的小部件。可以使用以下代码创建一个Text小部件: ``` Text( 'Hello, World!', // 要显示的文本内容 style: TextStyle( fontSize: 20.0, // 文本的字体大小 color: Colors.black, // 文本的颜色 ), ) ``` 在上面的代码中,文本内容被放置在引号中,并作为Text小部件的第一个参数传递给Text构造函数。可以根据需要更改文本的字体大小和颜色。 3. 将Text小部件添加到应用程序中:创建Text小部件后,需要将其添加到应用程序的UI层次结构中。可以将Text小部件作为视图部件的子部件添加到屏幕上的任何位置。 例如,可以将Text小部件添加到应用程序的主页小部件中: ``` class HomePage extends StatelessWidget { @override Widget build(BuildContext context) { return Scaffold( body: Center( child: Text( 'Hello, World!', style: TextStyle( fontSize: 20.0, color: Colors.black, ), ), ), ); } } ``` 在上面的代码中,Text小部件作为Center小部件的子部件添加到Scaffold小部件的body属性中。 4. 运行应用程序:完成以上步骤后,可以运行应用程序来查看Text组件所显示的文本内容。可以使用Flutter命令运行应用程序,或使用IDE中的运行按钮。 ``` flutter run ``` 这将在手机模拟器或连接的设备上启动应用程序,并显示Text组件中指定的文本内容。 以上是使用Flutter的Text组件的基本步骤。通过更改Text小部件的属性,例如字体大小和颜色,可以自定义显示的文本样式。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值