我的应用程序this中有类似的内容,我正在做的是击中一个api,如图所示。
但是为了在击中api时进行测试,我只是按原样提供json输出。 我正在获得我所期望的功能性智慧。
但是我要显示的是基于设备屏幕的,包含数据(总计,提交,失败,挂起)的容器应按照屏幕this对齐。进度条很好,但是根据屏幕的显示,卡片应该像这样。并正确地适应身体,
在我当前的代码中,容器可以滚动,并且每张卡都将在所有设备上以相同的大小显示,因此不能提供良好的用户体验,因此您可以帮助我将卡安装在任何屏幕上的容器侧面吗,< / p>
这是我的代码,
import 'package:flutter/material.dart';
import 'package:http/http.dart' as http;
import 'dart:convert';
import 'package:flutter/cupertino.dart';
import '../utils/radial_painter.dart';
import '../utils/provider_classes.dart';
class DashBoardView extends StatefulWidget {
@override
_DashBoardViewState createState() => _DashBoardViewState();
}
class _DashBoardViewState extends State<DashBoardView> {
Future reportList;
@override
void initState() {
super.initState();
reportList = getReport();
}
getReport() async {
http.Response response =
await http.get(reportsListURL, headers: {"token": "$token"});
switch (response.statusCode) {
case 200:
{
var resp =
"{\"statistic_cards\": [{\"title\":\"Total count\",\"value\":25,\"color\" : \"87CEEB\"},{\"title\":\"Submit\",\"value\":11,\"percentage\" : 0.48,\"progress_bar\" : false},{\"title\":\"Failed\",\"value\":30,\"percentage\" : 0.12},{\"title\":\"Pending\",\"value\":30,\"percentage\" : 0.25,\"progress_bar\" : false,\"color\" : \"87CEEB\"}]}";
var collection = json.decode(resp);
return collection;
}
break;
case 403:
case 401:
return null;
default:
return 1;
}
}
getDashBody(var data) {
double maxHeight = MediaQuery.of(context).size.height;
return Column(
children: <Widget>[
Container(
margin: new EdgeInsets.all(0.0),
// height: maxHeight - 145,
// height: maxHeight - 420,
height: MediaQuery.of(context).size.height*0.6,
child: createDashList(context, data),
),
],
);
}
Widget createDashList(BuildContext context, var data) {
Widget _listView = ListView.builder(
itemCount: data.length,
itemBuilder: (context, count) {
return createCard(context, count, data);
},
);
return _listView;
}
createCard(BuildContext context, int count, var data) {
var metrics = data["statistic_cards"].map<Widget>((cardInfo) {
var cardColor = getColorFromHexString(cardInfo["color"]);
if (cardInfo["percentage"] != null) {
return buildRadialProgressBar(
context: context,
progressPercent: cardInfo["percentage"],
color: cardColor,
count: cardInfo["value"],
title: cardInfo["title"],
);
} else {
return buildSubscriberTile(context, cardInfo, cardColor);
}
}).toList();
var rowMetrics = new List<Widget>();
for (int i = 0; i < metrics.length; i += 2) {
if (i + 2 <= metrics.length)
rowMetrics.add(Row(children: metrics.sublist(i, i + 2)));
else
rowMetrics.add(Row(children: [metrics[metrics.length - 1], Spacer()]));
}
return SingleChildScrollView(
child: LimitedBox(
// maxHeight: MediaQuery.of(context).size.height / 1.30,
child: Column(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.center,
children: rowMetrics,
),
),
);
}
Widget buildRadialProgressBar({
@required BuildContext context,
@required double progressPercent,
@required Color color,
@required int count,
@required String title,
}) {
return Expanded(
child: Container(
decoration: BoxDecoration(
border: Border.all(
color: Colors.grey,
width: 0.5,
),
),
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Padding(
padding: const EdgeInsets.symmetric(
horizontal: 10.0,
vertical: 5.0,
),
child: Text(
title,
style: TextStyle(
fontSize: 20.0,
fontWeight: FontWeight.bold,
),
),
),
Center(
child: Padding(
padding: const EdgeInsets.symmetric(vertical: 12.0),
child: Container(
padding: EdgeInsets.all(4.0),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(
MediaQuery.of(context).size.width / 6 + 13.0),
border: Border.all(color: color, width: 2.0)),
child: RadialProgressBar( // the dart file containing this is added below
progressColor: color,
progressPercent: progressPercent,
trackColor: Colors.transparent,
child: Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(
MediaQuery.of(context).size.width / 6),
),
width: MediaQuery.of(context).size.width / 3,
height: MediaQuery.of(context).size.width / 3,
child: Column(
mainAxisSize: MainAxisSize.min,
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text(
'$count',
style: TextStyle(
color: color,
fontWeight: FontWeight.bold,
fontSize:
MediaQuery.of(context).size.width / 10),
),
Text(
'${progressPercent * 100}%',
style: TextStyle(
color: color,
fontWeight: FontWeight.normal,
fontSize:
MediaQuery.of(context).size.width / 25),
),
],
),
),
),
),
),
),
],
),
),
);
}
Widget buildSubscriberTile(BuildContext context, var data, Color cardcolor) {
return Expanded(
child: Container(
decoration: BoxDecoration(
border: Border.all(
color: Colors.grey,
width: 0.5,
),
),
child: LimitedBox(
maxHeight: MediaQuery.of(context).size.width / 2 + 5.0,
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Padding(
padding:
const EdgeInsets.symmetric(horizontal: 8.0, vertical: 2.0),
child: Text(
data['title'],
style: TextStyle(
fontSize: 20.0,
fontWeight: FontWeight.bold,
color: Colors.black),
),
),
Expanded(
child: Center(
child: Text(
data['value'].toString(),
style: TextStyle(
color: cardcolor,
fontWeight: FontWeight.bold,
fontSize: MediaQuery.of(context).size.width / 6,
),
),
),
)
],
),
),
),
);
}
@override
Widget build(BuildContext context) {
return FutureBuilder(
future: reportList,
builder: (BuildContext context, AsyncSnapshot snapshot) {
switch (snapshot.connectionState) {
case ConnectionState.none:
case ConnectionState.waiting:
case ConnectionState.active:
return Center(
child: CircularProgressIndicator(),
);
case ConnectionState.done:
var data = snapshot.data;
if (snapshot.hasData && !snapshot.hasError) {
return getDashBody(data);
}
}
},
);
}
}
== radial_painter.dart文件==
import 'dart:math';
import 'package:flutter/material.dart';
class RadialProgressBar extends StatefulWidget {
final double trackWidth;
final Color trackColor;
final double progressWidth;
final Color progressColor;
final double progressPercent;
final EdgeInsets outerPadding;
final EdgeInsets innerPadding;
final Widget child;
RadialProgressBar({
this.progressColor = Colors.black,
this.progressWidth = 5.0,
this.progressPercent = 0.0,
this.trackColor = Colors.grey,
this.trackWidth = 3.0,
this.innerPadding = const EdgeInsets.all(0.0),
this.outerPadding = const EdgeInsets.all(0.0),
this.child,
});
@override
_RadialProgressBarState createState() => _RadialProgressBarState();
}
class _RadialProgressBarState extends State<RadialProgressBar> {
EdgeInsets _insetsForPainter() {
//Make room for painted track, progress and thumb. We divide by 2.0
// because we want to allow flush painting against the track, so we
// only need to account the thickness outside the track, not inside.
final outerThickness = max(
widget.trackWidth,
widget.progressWidth,
) /
2.0;
return EdgeInsets.all(outerThickness);
}
@override
Widget build(BuildContext context) {
return Padding(
padding: widget.outerPadding,
child: CustomPaint(
foregroundPainter: RadialSeekBarPainter(
trackWidth: widget.trackWidth,
trackColor: widget.trackColor,
progressWidth: widget.progressWidth,
progressColor: widget.progressColor,
progressPercent: widget.progressPercent,
),
child: Padding(
padding: _insetsForPainter() + widget.innerPadding,
child: widget.child,
),
),
);
}
}
class RadialSeekBarPainter extends CustomPainter {
final double trackWidth;
final Paint trackPaint;
final double progressWidth;
final Paint progressPaint;
final double progressPercent;
RadialSeekBarPainter({
progressColor,
@required this.progressPercent,
@required this.progressWidth,
@required trackColor,
@required this.trackWidth,
}) : trackPaint = Paint()
..color = trackColor
..style = PaintingStyle.stroke
..strokeWidth = trackWidth,
progressPaint = Paint()
..color = progressColor
..style = PaintingStyle.stroke
..strokeWidth = progressWidth
..strokeCap = StrokeCap.round;
@override
void paint(Canvas canvas, Size size) {
final outerThickness = max(trackWidth,progressWidth);
Size constrainedSize =
Size(size.width - outerThickness, size.height - outerThickness);
final center = Offset(size.width / 2, size.height / 2);
final radius = min(constrainedSize.width, constrainedSize.height) / 2;
//Paint Track.
canvas.drawCircle(
center,
radius,
trackPaint,
);
final progressAngle = 2 * pi * progressPercent;
//Paint Canvas.
canvas.drawArc(
Rect.fromCircle(
center: center,
radius: radius,
),
-pi / 2,
progressAngle,
false,
progressPaint);
}
@override
bool shouldRepaint(CustomPainter oldDelegate) {
return true;
}
}