我正在通过api调用加载图像,然后在图像的抖动和绘图边界框中以列表视图的形式显示该图像和一些数据,但是由于我的图像是从url加载的,因此UI会受到干扰,如何确保在网络布局中以浮动布局从画布加载图像后,Canvas会绘制。是否可以使用任何回调。
class ListPage extends StatefulWidget {
ListPage({Key key, this.title}) : super(key: key);
final String title;
@override
_ListPageState createState() => _ListPageState();
}
class _ListPageState extends State<ListPage> {
Future<List<ProcessedInference>> processInference;
@override
void initState() {
processInference = localInference();
super.initState();
}
@override
Widget build(BuildContext context) {
final toAppBar = AppBar(
elevation: 0.1,
backgroundColor: Color.fromRGBO(58, 66, 86, 1.0),
title: Text(widget.title),
actions: <Widget>[
IconButton(
icon: Icon(Icons.list),
onPressed: () {},
)
],
);
Card makeCard(ProcessedInference pro) => Card(
elevation: 2.0,
margin: new EdgeInsets.symmetric(horizontal: 5.0, vertical: 5.0),
child: Container(
child: Column(
children: <Widget>[
CustomPaint(
size: Size(640.0, 480.0),
foregroundPainter: RectPainter(pro.boundingBox),
child: Image.network(pro.frameUrl),
),
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
SizedBox(
height: 8.0,
),
Text(
"Spotted: ${pro.peopleCount}",
style: TextStyle(fontSize: 16.0),
textAlign: TextAlign.start,
),
SizedBox(
height: 8.0,
),
Text(
"Spotted on : ${pro.timeStamp}",
style: TextStyle(fontSize: 16.0),
textAlign: TextAlign.start,
),
SizedBox(
height: 8.0,
),
],
),
],
),
),
);
final makeBody = Container(
child: FutureBuilder<List<ProcessedInference>>(
future: processInference,
builder: (context, snapshot) {
if (snapshot.hasData) {
print("Has data");
if (snapshot.data == null || snapshot.data.length <= 0) {
return Center(
child: Text("No results", textAlign: TextAlign.center));
} else {
return ListView.builder(
scrollDirection: Axis.vertical,
shrinkWrap: true,
itemCount: snapshot.data.length,
itemBuilder: (BuildContext context, int index) {
return makeCard(snapshot.data[index]);
});
}
} else if (snapshot.hasError) {
print("has error ");
return Text("${snapshot.error}");
}
return CircularProgressIndicator();
},
),
);
return Scaffold(
appBar: toAppBar,
body: makeBody,
);
}
}
class RectPainter extends CustomPainter {
final List<List<double>> boundingBox;
RectPainter(this.boundingBox);
@override
void paint(Canvas canvas, Size size) {
final paint = Paint();
paint.color = Colors.deepOrange;
paint.style = PaintingStyle.stroke;
paint.strokeWidth = 2.0;
final boxPaint = Paint();
boxPaint.color = Colors.amberAccent;
boxPaint.style = PaintingStyle.fill;
boxPaint.strokeWidth = 2.0;
for (var i = 0; i < boundingBox.length; i++) {
var confidence = boundingBox[i][0];
var left = boundingBox[i][1] * size.width;
var top = boundingBox[i][2] * size.height;
var right = boundingBox[i][3] * size.width;
var bottom = boundingBox[i][4] * size.height;
var rect = Rect.fromLTRB(left, top - 15, right, bottom);
canvas.drawRect(rect, paint);
TextSpan span = new TextSpan(
style: new TextStyle(color: Colors.red[600], fontSize: 10.0),
text: confidence.toStringAsFixed(2));
TextPainter tp = new TextPainter(
text: span,
textAlign: TextAlign.center,
textDirection: TextDirection.ltr);
tp.layout();
canvas.drawRect(
Rect.fromLTRB(
rect.left, rect.top, rect.left + tp.width, rect.top + tp.height),
boxPaint);
tp.paint(canvas, new Offset(rect.left, rect.top));
}
}
@override
bool shouldRepaint(CustomPainter oldDelegate) {
return false;
}
}