为了优化FPS,我决定渲染并显示小部件。我的文字有问题,因为文字被剪掉了,我不知道为什么。下面的示例显示了我的“ RenderedTextWithStroke”的外观和代码。
我在三星S7上进行了测试。当我输入“ Wyzwanie!”字样时在三行中,中线呈现良好。也许问题出在渲染小部件的边缘。我可以增加渲染的小部件的大小吗?
import 'dart:typed_data';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart';
import 'package:meloapp/core/utils/logger.dart';
import 'package:meloapp/core/utils/screen_information/sizing_information.dart';
import 'package:meloapp/core/values/styles.dart';
import 'dart:ui' as ui;
class TextWithStrokeRendered extends StatelessWidget {
final double fontSize;
final Color strokeColor;
final Color backgroundColor;
final String text;
String font;
double strokeWidth;
TextAlign alignment;
final _globalKey = GlobalKey();
Widget imageWidget;
static const _MAX_ATTEMPTS_TO_LOAD_IMAGE = 5;
int attempts = 0;
TextWithStrokeRendered({Key key,
@required this.text,
@required this.strokeColor,
@required this.fontSize,
@required this.backgroundColor,
this.font,
this.strokeWidth,
this.alignment: TextAlign.start})
: super(key: key) {
if (strokeWidth == null) {
strokeWidth = fontSize / 5;
}
if (font == null) {
font = defaultFont;
}
}
@override
Widget build(BuildContext context) {
return imageWidget ??
FutureBuilder<Widget>(
future: _captureImage(context),
builder: (context, snapshot) {
if (snapshot.hasData) {
return snapshot.data;
} else {
return RepaintBoundary(
key: _globalKey,
child: Material(
type: MaterialType.transparency,
child: Stack(
children: <Widget>[
// Stroked text as border.
Text(
text,
style: TextStyle(
fontSize: fontSize,
fontFamily: font,
height: 1.0,
foreground: Paint()
..style = PaintingStyle.stroke
..strokeWidth = strokeWidth
..color = strokeColor,
),
textAlign: alignment,
),
// Solid text as fill.
Text(
text,
style: TextStyle(
fontSize: fontSize,
fontFamily: font,
height: 1.0,
color: backgroundColor,
),
textAlign: alignment,
),
],
)));
}
});
}
Future<Widget> _captureImage(BuildContext context) async {
Logger.debug("Start capture image from stroke text $text");
while (imageWidget == null) {
try {
await Future.delayed(Duration(milliseconds: 50));
attempts++;
if (attempts >= _MAX_ATTEMPTS_TO_LOAD_IMAGE) break;
if (_globalKey.currentContext == null) {
await Future.delayed(Duration(milliseconds: 50));
if (_globalKey.currentContext == null) continue;
}
RenderRepaintBoundary boundary = _globalKey.currentContext.findRenderObject();
if (boundary.debugNeedsPaint) {
continue;
}
ui.Image image = await boundary.toImage(pixelRatio: SizingInformation.devicePixelRatio ?? 1.0);
ByteData byteData = await image.toByteData(format: ui.ImageByteFormat.png);
final pngBytes = byteData.buffer.asUint8List();
precacheImage(MemoryImage(pngBytes, scale: SizingInformation.devicePixelRatio ?? 1.0), context);
await Future.delayed(Duration(milliseconds: 20));
imageWidget = Image.memory(
pngBytes,
scale: SizingInformation.devicePixelRatio ?? 1.0,
fit: BoxFit.scaleDown,
);
Logger.debug("Image captured $text");
return imageWidget;
} catch (exception) {
Logger.logError(exception);
}
}
}
}