How to show progress bar with dots indicating the progress? - dart

How to make a widget indicating the progress look like the attached image?

Well, you can actually create it yourself by extending a CustomPainter class and then insert it in your widget tree with a CustomPaint widget.
I've actually managed to provide an example for you, feel free to tweak it for your needs. The result is something like this:
class MyDeliveryProgress extends StatefulWidget {
_StepperState createState() => _StepperState();
}
class _StepperState extends State<MyDeliveryProgress> {
#override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: Padding(
padding: const EdgeInsets.only(left: 10.0, right: 10.0),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
Expanded(
child: RichText(
text: TextSpan(
text: 'Ordered',
style: TextStyle(color: Colors.black, fontWeight: FontWeight.bold),
children: [
TextSpan(
text: '\n20 Dec',
style: TextStyle(fontWeight: FontWeight.normal),
),
]),
textAlign: TextAlign.center,
)),
//Text('Ordered'),
Expanded(
flex: 3,
child: IntrinsicHeight(
child: Column(
mainAxisSize: MainAxisSize.max,
children: <Widget>[
Expanded(
child: Text(
'Shipped (${DateTime.now().day.toString()} Dec)',
style: TextStyle(fontWeight: FontWeight.bold),
textAlign: TextAlign.center,
),
),
Expanded(
child: Padding(
padding: const EdgeInsets.only(top: 10.0),
child: CustomPaint(
painter: MyProgressLine(
estDelivery: DateTime(2019, 1, 1),
shipped: DateTime(2018, 12, 20),
),
child: Container(
width: double.infinity,
height: 5.0,
),
),
),
),
],
),
)),
Expanded(
child: RichText(
text: TextSpan(
text: 'Delivery',
style: TextStyle(color: Colors.black, fontWeight: FontWeight.bold),
children: [
TextSpan(
text: '\n1 Jan',
style: TextStyle(fontWeight: FontWeight.normal),
),
]),
textAlign: TextAlign.center,
)),
],
),
)));
}
}
class MyProgressLine extends CustomPainter {
MyProgressLine({this.shipped, this.estDelivery});
final DateTime shipped;
final DateTime estDelivery;
#override
void paint(Canvas canvas, Size size) {
Paint paint = Paint()
..color = Colors.green
..strokeWidth = 3.0
..style = PaintingStyle.stroke;
double endPointsRadius = 5.0;
double width = size.width;
int totalDays = ((estDelivery.millisecondsSinceEpoch - shipped.millisecondsSinceEpoch) / 86400000).floor();
int currentDay = ((DateTime.now().millisecondsSinceEpoch - shipped.millisecondsSinceEpoch) / 86400000).floor();
double stepPerDay = width / totalDays;
// Draws starting point
canvas.drawCircle(Offset.zero, endPointsRadius, paint);
canvas.drawLine(Offset(endPointsRadius, 0.0), Offset(endPointsRadius + stepPerDay * currentDay, 0.0), paint);
// Draws current progress line
paint.style = PaintingStyle.fill;
canvas.drawCircle(Offset(endPointsRadius + stepPerDay * currentDay, 0.0), 3.0, paint);
// Draws endpoint
paint.style = PaintingStyle.stroke;
paint.color = Colors.grey.withOpacity(0.5);
canvas.drawLine(Offset(endPointsRadius + stepPerDay * currentDay, 0.0), Offset(stepPerDay * totalDays, 0.0), paint);
canvas.drawCircle(Offset((stepPerDay * totalDays) + endPointsRadius, 0.0), endPointsRadius, paint);
}
#override
bool shouldRepaint(CustomPainter oldDelegate) => false;
}

Related

VideoEditorController breaks all VideoPlayers in parent widgets

I have a page where I crop and trim the video.
When I initialize a VideoEditorController and for example edit the video, or just navigate back to previous page. And then I get method channel error and all CachedVideoPlayer widgets show a black screen. if we rebuild the widget with CachedVideoPlayer it'll play. And if we try to repeat the same process again for some strange reason CachedVideoPlayers won't crash.
I'm testing on a real device(Iphone 12 mini).
Error:
MissingPluginException(No implementation found for method cancel on channel flutter.io/videoPlayer/videoEvents171)
How I initialize VideoEditorController
#override
void initState() {
super.initState();
_controller = VideoEditorController.file(widget.file,
maxDuration: const Duration(seconds: 30))
..initialize().then((_) => setState(() {
_controller.preferredCropAspectRatio = widget.aspectRatio;
showTrimmer = true;
}));
}
CropScreen
class CropScreen extends StatefulWidget {
const CropScreen({
Key? key,
required this.file,
required this.exportedFile,
required this.aspectRatio,
}) : super(key: key);
final File file;
final double aspectRatio;
final Function(File) exportedFile;
#override
State<CropScreen> createState() => _CropScreenState();
}
class _CropScreenState extends State<CropScreen> {
late VideoEditorController _controller;
final double height = 60;
bool showTrimmer = false;
final ValueNotifier<bool> _isLoadingNotifier = ValueNotifier(false);
void show() {
_isLoadingNotifier.value = true;
}
void hide() {
_isLoadingNotifier.value = false;
}
#override
void initState() {
super.initState();
_controller = VideoEditorController.file(widget.file,
maxDuration: const Duration(seconds: 30))
..initialize().then((_) => setState(() {
_controller.preferredCropAspectRatio = widget.aspectRatio;
showTrimmer = true;
}));
}
#override
void dispose() {
// TODO: implement dispose
super.dispose();
_controller.dispose();
}
#override
Widget build(BuildContext context) {
return ValueListenableBuilder<bool>(
valueListenable: _isLoadingNotifier,
builder: (context, value, child) {
return Stack(
children: [
Stack(
children: [
Scaffold(
backgroundColor: Colors.black,
body: SafeArea(
child: Padding(
padding: const EdgeInsets.all(30),
child: Column(children: [
Row(children: [
Expanded(
child: IconButton(
onPressed: () => _controller
.rotate90Degrees(RotateDirection.left),
icon: const Icon(
Icons.rotate_left,
color: white,
),
),
),
Expanded(
child: IconButton(
onPressed: () => _controller
.rotate90Degrees(RotateDirection.right),
icon: const Icon(
Icons.rotate_right,
color: white,
),
),
)
]),
const SizedBox(height: 15),
Expanded(
child: CropGridViewer(
controller: _controller, horizontalMargin: 60),
),
const SizedBox(
height: 15,
),
showTrimmer
? Column(
mainAxisAlignment: MainAxisAlignment.center,
children: _trimSlider(context))
: SizedBox(height: 100),
const SizedBox(height: 15),
Row(children: [
Expanded(
child: IconButton(
onPressed: () {
Navigator.pop(context);
},
icon: Center(
child: Text(
"Cancel",
style: MainTheme.of(context)
.bodyText1
.copyWith(fontWeight: FontWeight.w600),
),
),
),
),
buildSplashTap("21:9", 21 / 9,
padding:
const EdgeInsets.symmetric(horizontal: 10)),
buildSplashTap("1:1", 1 / 1),
buildSplashTap("4:5", 4 / 5,
padding:
const EdgeInsets.symmetric(horizontal: 10)),
buildSplashTap("NO", null,
padding: const EdgeInsets.only(right: 10)),
Expanded(
child: IconButton(
onPressed: () async {
//2 WAYS TO UPDATE CROP
//WAY 1:
show();
_controller.updateCrop();
await _controller.exportVideo(
onCompleted: (file) {
print(file!.path);
widget.exportedFile(file);
hide();
Navigator.pop(context);
});
/*WAY 2:
controller.minCrop = controller.cacheMinCrop;
controller.maxCrop = controller.cacheMaxCrop;
*/
},
icon: Center(
child: Text(
"Crop",
style: MainTheme.of(context)
.bodyText1
.copyWith(fontWeight: FontWeight.w600),
),
),
),
),
]),
]),
),
),
),
],
),
if (value)
BackdropFilter(
filter: ImageFilter.blur(sigmaX: 4.0, sigmaY: 4.0),
child: const Opacity(
opacity: 0.8,
child:
ModalBarrier(dismissible: false, color: Colors.black),
),
),
if (value)
Center(
child: FutureBuilder(
future: Future.delayed(Duration(milliseconds: 500)),
builder: (context, snapshot) {
return const SpinKitFadingCircle(
size: 60, color: primary);
},
),
),
],
);
});
}
Widget buildSplashTap(
String title,
double? aspectRatio, {
EdgeInsetsGeometry? padding,
}) {
return InkWell(
onTap: () => _controller.preferredCropAspectRatio = aspectRatio,
child: Padding(
padding: padding ?? EdgeInsets.zero,
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
const Icon(Icons.aspect_ratio, color: Colors.white),
Text(
title,
style: const TextStyle(fontWeight: FontWeight.bold, color: white),
),
],
),
),
);
}
List<Widget> _trimSlider(BuildContext context) {
return [
AnimatedBuilder(
animation: _controller.video,
builder: (_, __) {
final duration = _controller.video.value.duration.inSeconds;
final pos = _controller.trimPosition * duration;
final start = _controller.minTrim * duration;
final end = _controller.maxTrim * duration;
return Padding(
padding: EdgeInsets.symmetric(horizontal: height / 4),
child: Row(children: [
Text(
formatter(Duration(seconds: pos.toInt())),
style: MainTheme.of(context).bodyText1,
),
const Expanded(child: SizedBox()),
OpacityTransition(
visible: _controller.isTrimming,
child: Row(mainAxisSize: MainAxisSize.min, children: [
Text(
formatter(Duration(seconds: start.toInt())),
style: MainTheme.of(context).bodyText1,
),
const SizedBox(width: 10),
Text(
formatter(Duration(seconds: end.toInt())),
style: MainTheme.of(context).bodyText1,
),
]),
)
]),
);
},
),
Container(
width: MediaQuery.of(context).size.width,
margin: EdgeInsets.symmetric(vertical: height / 4),
child: TrimSlider(
controller: _controller,
height: height,
horizontalMargin: height / 4,
child: TrimTimeline(
controller: _controller,
margin: const EdgeInsets.only(top: 10))),
)
];
}
String formatter(Duration duration) => [
duration.inMinutes.remainder(60).toString().padLeft(2, '0'),
duration.inSeconds.remainder(60).toString().padLeft(2, '0')
].join(":");
}
To use VideoEditorController you need to add this package:
video_editor: ^1.4.1
Dart SDK:
sdk: ">=2.16.1 <3.0.0"

How to change from Stateless Widget to Stateful Widget?

I have an app screen that uses Checkboxes and a Drop down Menu. However, I have realised I'd coded it inside a StatelessWidget so I am unable to change the state when an option is selected. How do I get this working so that when a Checkbox is selected then it will display as being "checked" rather than empty?
I have tried pasting in my code into a Stateful Widget, however keep running into errors, as I am not totally sure on which parts should go where.
import 'package:carve_brace_app/model/activity.dart';
import 'package:flutter/material.dart';
class DetailPage extends StatelessWidget {
final Activity activity;
DetailPage({Key key, this.activity}) : super(key: key);
#override
Widget build(BuildContext context) {
final levelIndicator = Container(
child: Container(
child: LinearProgressIndicator(
backgroundColor: Color.fromRGBO(209, 224, 224, 0.2),
value: 2.0,
valueColor: AlwaysStoppedAnimation(Colors.green)),
),
);
final topContentText = Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
SizedBox(height: 120.0),
Container(
width: 90.0,
child: new Divider(color: Colors.green),
),
SizedBox(height: 10.0),
Text(
activity.activityName,
style: TextStyle(color: Colors.white, fontSize: 45.0),
),
SizedBox(height: 30.0),
Row(
mainAxisAlignment: MainAxisAlignment.start,
children: <Widget>[
Expanded(
flex: 6,
child: Padding(
padding: EdgeInsets.only(left: 10.0),
child: Text(
"Last Run: 3-2-19\n"+
"Last Avg Strain: 34%\n"+
"Last Run Time: 00:45:23",
style: TextStyle(color: Colors.white),
))),
// Expanded(flex: 1, child: newRow)
],
),
],
);
final topContent = Stack(
children: <Widget>[
Container(
height: MediaQuery.of(context).size.height * 0.45,
padding: EdgeInsets.all(40.0),
width: MediaQuery.of(context).size.width,
decoration: BoxDecoration(
gradient: LinearGradient(
begin: Alignment.centerLeft,
end: Alignment.centerRight,
colors: [
Color.fromRGBO(33, 147, 176, 100),
Color.fromRGBO(109, 213, 237, 100)
],
),
),
child: Center(
child: topContentText,
),
),
Positioned(
left: 235.0,
top: 180.0,
child: InkWell(
onTap: () {
Navigator.pop(context);
},
child: new CircleAvatar(
radius: 80.0,
backgroundImage: NetworkImage(activity.icon),
backgroundColor: Colors.white,
),
),
),
Positioned(
left: 8.0,
top: 60.0,
child: InkWell(
onTap: () {
Navigator.pop(context);
},
child: Icon(Icons.arrow_back, color: Colors.white),
),
)
],
);
final bottomContentText = Text(
"Config:",
style: TextStyle(fontSize: 18.0),
);
final mappedCheckbox = CheckboxListTile(
title: Text("Mapped"),
value: false,
onChanged: (newValue) { },
controlAffinity: ListTileControlAffinity.leading, // <-- leading Checkbox
);
final rtCheckBox = CheckboxListTile(
title: Text("Real-time Tracking"),
value: false,
onChanged: (newValue) { },
controlAffinity: ListTileControlAffinity.leading, // <-- leading Checkbox
);
final descriptionText = Text(
"Description:",
style: TextStyle(fontSize: 12.0),
);
final description = TextFormField(
decoration: InputDecoration(
hintText: 'Enter an activity description',
),
);
final scheduledFor = Text(
"Scheduled for:",
style: TextStyle(fontSize: 12.0),
);
final dropdown = new DropdownButton<String>(
items: <String>['Now (Default)', 'B', 'C', 'D'].map((String value) {
return new DropdownMenuItem<String>(
value: value,
child: new Text(value),
);
}).toList(),
hint: Text("Now (Default)"),
onChanged: (_) {},
);
final readButton = Container(
padding: EdgeInsets.symmetric(vertical: 16.0),
width: 170,//MediaQuery.of(context).size.width,
child: RaisedButton(
onPressed: () => {},
color: Colors.lightBlue,
child:
Text("Start", style: TextStyle(color: Colors.white, fontSize: 20)),
));
final bottomContent = Container(
width: MediaQuery.of(context).size.width,
padding: EdgeInsets.all(40.0),
child: Center(
child: Column(
children: <Widget>[bottomContentText, mappedCheckbox, rtCheckBox, descriptionText, description, Text("\n"), scheduledFor, dropdown, readButton],
),
),
);
return Scaffold(
body: Column(
children: <Widget>[topContent, bottomContent],
),
);
}
}
Hover on to the StatelessWidget class and use
Android Studio:
Mac: option + enter
Windows: alt + enter
Visual Studio Code:
Mac: cmd + .
Windows: ctrl + .
Output (Your solution):
Here is the working code.
class DetailPage extends StatefulWidget {
final Activity activity;
DetailPage({Key key, this.activity}) : super(key: key);
#override
_DetailPageState createState() => _DetailPageState();
}
class _DetailPageState extends State<DetailPage> {
bool _tracking = false, _mapped = false; // you need this
String _schedule;
#override
Widget build(BuildContext context) {
final levelIndicator = Container(
child: Container(
child: LinearProgressIndicator(backgroundColor: Color.fromRGBO(209, 224, 224, 0.2), value: 2.0, valueColor: AlwaysStoppedAnimation(Colors.green)),
),
);
final topContentText = Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
SizedBox(height: 120.0),
Container(
width: 90.0,
child: Divider(color: Colors.green),
),
SizedBox(height: 10.0),
Text(
widget.activity.activityName,
style: TextStyle(color: Colors.white, fontSize: 45.0),
),
SizedBox(height: 30.0),
Row(
mainAxisAlignment: MainAxisAlignment.start,
children: <Widget>[
Expanded(
flex: 6,
child: Padding(
padding: EdgeInsets.only(left: 10.0),
child: Text(
"Last Run: 3-2-19\n" + "Last Avg Strain: 34%\n" + "Last Run Time: 00:45:23",
style: TextStyle(color: Colors.white),
))),
// Expanded(flex: 1, child: newRow)
],
),
],
);
final topContent = Stack(
children: <Widget>[
Container(
height: MediaQuery.of(context).size.height * 0.45,
padding: EdgeInsets.all(40.0),
width: MediaQuery.of(context).size.width,
decoration: BoxDecoration(
gradient: LinearGradient(
begin: Alignment.centerLeft,
end: Alignment.centerRight,
colors: [Color.fromRGBO(33, 147, 176, 100), Color.fromRGBO(109, 213, 237, 100)],
),
),
child: Center(
child: topContentText,
),
),
Positioned(
left: 235.0,
top: 180.0,
child: InkWell(
onTap: () {
Navigator.pop(context);
},
child: CircleAvatar(
radius: 80.0,
backgroundColor: Colors.white,
),
),
),
Positioned(
left: 8.0,
top: 60.0,
child: InkWell(
onTap: () {
Navigator.pop(context);
},
child: Icon(Icons.arrow_back, color: Colors.white),
),
)
],
);
final bottomContentText = Text(
"Config:",
style: TextStyle(fontSize: 18.0),
);
final mappedCheckbox = CheckboxListTile(
title: Text("Mapped"),
value: _mapped,
onChanged: (newValue) => setState(() => _mapped = newValue),
controlAffinity: ListTileControlAffinity.leading, // <-- leading Checkbox
);
final rtCheckBox = CheckboxListTile(
title: Text("Real-time Tracking"),
value: _tracking,
onChanged: (newValue) => setState(() => _tracking = newValue),
controlAffinity: ListTileControlAffinity.leading, // <-- leading Checkbox
);
final descriptionText = Text(
"Description:",
style: TextStyle(fontSize: 12.0),
);
final description = TextFormField(
decoration: InputDecoration(
hintText: 'Enter an activity description',
),
);
final scheduledFor = Text(
"Scheduled for:",
style: TextStyle(fontSize: 12.0),
);
final dropdown = DropdownButton<String>(
value: _schedule,
items: <String>['Now (Default)', 'B', 'C', 'D'].map((String value) {
return DropdownMenuItem<String>(
value: value,
child: Text(value),
);
}).toList(),
hint: Text("Now (Default)"),
onChanged: (newValue) {
setState(() {
_schedule = newValue;
});
},
);
final readButton = Container(
padding: EdgeInsets.symmetric(vertical: 16.0),
width: 170, //MediaQuery.of(context).size.width,
child: RaisedButton(
onPressed: () => {},
color: Colors.lightBlue,
child: Text("Start", style: TextStyle(color: Colors.white, fontSize: 20)),
));
final bottomContent = Container(
width: MediaQuery.of(context).size.width,
padding: EdgeInsets.all(40.0),
child: Center(
child: Column(
children: <Widget>[bottomContentText, mappedCheckbox, rtCheckBox, descriptionText, description, Text("\n"), scheduledFor, dropdown, readButton],
),
),
);
return Scaffold(
body: Column(
children: <Widget>[topContent, bottomContent],
),
);
}
}
For VSCode (Visual Studio Code) use ctrl + '.' keys while the cursor on the stateless widget to convert it to stateful widget.
You could use intellij's or vscode shortcut by hitting alt + enter or selecting the bulb icon while your cursor is on the name of the stateless widget then select convert to stateful widget
For Android Studio in Mac:
1.Place the marker on the Stateless widget name
2.Hit Alt+Enter
3.Select Convert to Stateful widget
4.Configure your Stateful widget based on your requirements
Adding a solution for Android Studio since I didn't find one here.
Place the marker on the Stateless widget name:
Hit Alt+Enter
Select Convert to Stateful widget
Configure your Stateful widget based on your requirements

Decide which type to construct during runtime

I am trying to get more into Flutter.
I have a button class that either builds a FlatButton or an OutlineButton depending on a parameter
import 'package:flutter/material.dart';
class Button extends StatelessWidget {
final String text;
final VoidCallback onPressed;
final Color backgroundColor;
final Color textColor;
final bool isOutline;
Button(
{#required this.text,
#required this.onPressed,
this.backgroundColor = Colors.deepOrange,
this.textColor = Colors.white,
this.isOutline = false});
#override
Widget build(BuildContext context) {
return this.isOutline
? _buildOutlineButton(context)
: _buildFlatButton(context);
}
FlatButton _buildFlatButton(BuildContext context) {
return FlatButton(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(30.0),
),
color: this.backgroundColor,
onPressed: this.onPressed,
child: Container(
padding: const EdgeInsets.symmetric(
vertical: 20.0,
horizontal: 20.0,
),
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Expanded(
child: Text(
this.text,
textAlign: TextAlign.center,
style:
TextStyle(color: this.textColor, fontWeight: FontWeight.bold),
),
),
],
),
),
);
}
OutlineButton _buildOutlineButton(BuildContext context) {
return OutlineButton(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(30.0),
),
color: this.backgroundColor,
onPressed: this.onPressed,
child: Container(
padding: const EdgeInsets.symmetric(
vertical: 20.0,
horizontal: 20.0,
),
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Expanded(
child: Text(
this.text,
textAlign: TextAlign.center,
style:
TextStyle(color: this.textColor, fontWeight: FontWeight.bold),
),
),
],
),
),
);
}
}
As you can see, both _build*Button functions look similar. Is there a way to simply the code? Something like that (pseudo-code ahead):
final type = this.isOutline ? OutlineButton : FlatButton;
return type(shape: ..., color: ..., ...);
You can share much of the common code like this:
MaterialButton _buildButton(bool flat, BuildContext context) {
Container container = Container(
padding: const EdgeInsets.symmetric(
vertical: 20.0,
horizontal: 20.0,
),
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Expanded(
child: Text(
text,
textAlign: TextAlign.center,
style: TextStyle(color: textColor, fontWeight: FontWeight.bold),
),
),
],
),
);
RoundedRectangleBorder border = RoundedRectangleBorder(
borderRadius: BorderRadius.circular(30.0),
);
return flat
? FlatButton(
shape: border,
color: backgroundColor,
onPressed: onPressed,
child: container,
)
: RaisedButton(
shape: border,
color: backgroundColor,
onPressed: onPressed,
child: container,
);
}

setState() only updates with List.generate [duplicate]

This question already has answers here:
ListView does not refresh whereas attached list does (Flutter)
(2 answers)
Closed 4 years ago.
I'm trying to create an app where I am able to get data from Cloud Firestore and create multiple custom widgets with the data.
The custom widget is eventCardWidget
import 'package:flutter/material.dart';
import 'package:do_and_stuff/settings/theme.dart';
class EventCardWidget extends StatelessWidget {
EventCardWidget(this.eventImage, this.eventTitle, this.eventDescription,
this.eventAddress, this.eventDate, this.eventTime, this.peopleRequired);
String eventTitle;
String eventAddress;
String eventDate;
String eventImage;
String eventTime;
String eventDescription;
int peopleRequired;
#override
Widget build(BuildContext context) {
return Material(
child: GestureDetector(
child: InkWell(
splashColor: ThemeSettings.CardInkwell,
onTap: () {},
child: Card(
elevation: 1.0,
margin: const EdgeInsets.symmetric(vertical: 8.0, horizontal: 14.0),
child: Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Container(
margin: const EdgeInsets.only(right: 19.0),
width: 100.0,
height: 100.0,
child: Image.asset(this.eventImage, scale: .5),
),
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Row(
children: <Widget>[
Expanded(
child: Container(
margin: const EdgeInsets.only(
top: 12.0, bottom: 10.0),
child: Text(
eventTitle,
style: TextStyle(
fontSize: 18.0,
color: Colors.black,
fontWeight: FontWeight.bold,
),
),
),
),
Container(
margin: const EdgeInsets.only(right: 10.0),
child: Text(
this.eventAddress,
style: TextStyle(
fontSize: 16.0,
fontWeight: FontWeight.bold,
color: Colors.grey[600]),
),
),
],
),
Container(
margin: const EdgeInsets.only(right: 10.0),
child: Text(
this.eventDescription,
style: TextStyle(
fontSize: 16.0,
),
maxLines: 3,
overflow: TextOverflow.ellipsis,
),
),
Container(
padding: EdgeInsets.fromLTRB(0.0, 25.0, 0.0, 0.0),
margin: const EdgeInsets.only(top: 10.0),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
Text(
this.eventDate,
style: TextStyle(
color: Colors.grey[500],
fontSize: 11.0,
),
),
Container(
margin: const EdgeInsets.only(right: 10.0),
child: Text(peopleRequired.toString())),
],
),
),
],
),
),
],
),
),
),
),
);
}
}
Now, above my Widget build(BuildContext context) {
I have
List<Widget> cards = [];
and then within the Widget build(BuildContext context) { I have children: cards,
So at this point, this page would open up with cards being initialized empty.
But, I now have
void initState() {
super.initState();
WidgetsBinding.instance.addPostFrameCallback((_) async {
final List results = await db.getEvent(
DateFormat("y-MM-dd").format(DateTime.now()),
DateFormat("y-MM-dd").format(DateTime.now().add(Duration(days: 20))),
2,
);
for (DocumentSnapshot result in results) {
cards.add(EventCardWidget(
"assets/flutter-icon.png",
result.data.values
.toList()[result.data.keys.toList().indexOf("name")],
result.data.values
.toList()[result.data.keys.toList().indexOf("description")],
"1 mi",
"2018-10-29",
// result.data.values
// .toList()[result.data.keys.toList().indexOf("eventDate")],
"Time",
result.data.values
.toList()[result.data.keys.toList().indexOf("num")],
));
setState(() {
return cards;
});
}
});
}
Now, in Android Studio, I am able to see that cards has more elements when I set breakpoints, but nothing updates on the screen.
Now what's weird, is that when I do something like
void initState() {
super.initState();
WidgetsBinding.instance.addPostFrameCallback((_) async {
final List results = await db.getEvent(
DateFormat("y-MM-dd").format(DateTime.now()),
DateFormat("y-MM-dd").format(DateTime.now().add(Duration(days: 20))),
2,
);
for (DocumentSnapshot result in results) {
setState(() {
return cards = List.generate(
3,
(i) => new EventCardWidget(
"assets/flutter-icon.png",
"Title",
"Description",
"12 mi",
"2018-10-29",
"Time",
5),
growable: true,
);
});
}
});
}
Then the text on the screen updates.
Any ideas?
This is not a duplicate because I have tried the solution Here and it still does not work
for (DocumentSnapshot result in results) {
setState(() {
cards = List.from(cards)
..add(EventCardWidget(
"assets/flutter-icon.png",
result.data.values
.toList()[result.data.keys.toList().indexOf("name")],
result.data.values
.toList()[result.data.keys.toList().indexOf("description")],
"1 mi",
"2018-10-29",
result.data.values.toList()[
result.data.keys.toList().indexOf("peopleRequired")],
));
});
}
Your code started working for me when I did this
for (DocumentSnapshot result in results) {
cards = List.from(cards)
..add(EventCardWidget(
"assets/flutter-icon.png",
result.data.values
.toList()[result.data.keys.toList().indexOf("name")],
result.data.values
.toList()[result.data.keys.toList().indexOf("description")],
"1 mi",
"2018-10-29",
"8:00pm",
result.data.values
.toList()[result.data.keys.toList().indexOf("peopleRequired")],
));
setState(() {
this.cards = cards;
});
}

How to display data under padding in flutter?

Map item;
List data;
Future getdata() async{
http.Response response= await http.get(Uri.encodeFull("https://talaikis.com/api/quotes/"));
item=json.decode(response.body);
setState(() {
data=item["quotes"];
});
debugPrint(data.toString());
}
I want to display this request in stateful widget which is like this
#override
Widget build(BuildContext context) {
return new Scaffold(
drawer: drawerLeft(),
appBar: AppBar(
title: Text(
"IN TIME",
style: TextStyle(color: Colors.black, fontWeight: FontWeight.w700),
),
backgroundColor: clr,
elevation: 0.0,
leading: MaterialButton(
child: Icon(
Icons.view_headline,
color: Colors.black,
),
onPressed: () {
scaffoldKey.currentState.openDrawer();
},
)),
key: scaffoldKey,
body: AnimatedContainer(
padding: EdgeInsets.only(top: 50.0),
duration: Duration(milliseconds: 1000),
curve: Curves.ease,
color: clr,
child: PageView.builder(
itemCount: 7, //7days
onPageChanged: (int page) {
this.setState(() {
Random rnd;
rnd = new Random();
int r = 0 + rnd.nextInt(_colors.length - 0);
clr = _colors[r];
});
},
controller: pageViewController,
itemBuilder: (BuildContext context, int index) {
return Padding(
padding: const EdgeInsets.only(left: 10.0),
child: Stack(
children: <Widget>[
Container(
decoration: new BoxDecoration(
borderRadius: BorderRadius.circular(20.0),
color: Colors.white,
),
height:
MediaQuery.of(scaffoldKey.currentContext).size.height -
150.0,
width:
MediaQuery.of(scaffoldKey.currentContext).size.width -
20.0,
child: Stack(
children: <Widget>[
Positioned(
width: MediaQuery.of(scaffoldKey.currentContext)
.size
.width -
100.0,
left: index != currentPage
? getMappedValue(20.0, 100.0, 160.0, 20.0, pos)
: getMappedValue(20.0, 100.0, 20.0, -120.0, pos),
top: 20.0,
child: Opacity(
opacity: index != currentPage
? getMappedValue(20.0, 100.0, 0.0, 01.0, pos)
: getMappedValue(20.0, 100.0, 01.0, 00.0, pos),
child: Column(
children: <Widget>[
Row(
mainAxisAlignment:
MainAxisAlignment.spaceBetween,
children: <Widget>[
Text(
_days[index],
maxLines: 1,
softWrap: true,
style: TextStyle(
color: Colors.deepOrange,
fontSize: 22.0,
fontWeight: FontWeight.w600),
),
],
),
Padding(
padding: const EdgeInsets.only(top: 15.0),
child: Text(
'Quote for the day',
softWrap: true,
style: TextStyle(
fontSize: 30.0,
fontWeight: FontWeight.w300),
),
),
],
),
),
),
],
),
),
],
),
);
},
),
),
);
}
}
*Please help me out *
If I understand, you want to display the quotes under some padding that are being retrieved to your List which I'll assume to be an inferenced List<String>. If so, you could just use a ListView within your widget tree to display every fetched item in that list, like so:
(...)
data != null
? Padding(
padding: const EdgeInsets.only(top: 15.0),
child: ListView.builder(
itemCount: data.length,
itemBuilder: (BuildContext context, int index) {
return ListTile(
title: Text(data[index]),
);
},
),
)
: Container(),
(...)

Resources