Flutter - How do I get different results using the same future? - flutter

I am trying to get a different Times set by the user on each button. But show the same time for all of them. Whenever I change it, it changes the time of all their text. How do I do it, please explain?
This is my code:
import 'package:flutter/material.dart';
import 'package:flutter_duration_picker/flutter_duration_picker.dart';
import 'dart:async';
class EndurancePage extends StatefulWidget {
#override
_EndurancePageState createState() => _EndurancePageState();
}
class _EndurancePageState extends State<EndurancePage> {
Duration _duration = Duration();
Future<Null> _selectTime(BuildContext context) async {
final Duration picked =
await showDurationPicker(context: context, initialTime: _duration);
if (picked != null && picked != _duration) {
print('Time Selected: ${_duration.toString()}');
setState(() {
_duration = picked;
});
} }
#override
Widget build(BuildContext context) {
return SingleChildScrollView(
child: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Padding(
padding: EdgeInsets.only(top: 100.0, bottom: 30.0),
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text(
"Excer",
textAlign: TextAlign.center,
style:
const TextStyle(fontSize: 35.0, color: Colors.white),
),
Text(
"sices",
textAlign: TextAlign.center,
style: const TextStyle(
fontSize: 35.0,
color: Colors.white,
fontWeight: FontWeight.bold),
),
]),
),
Padding(
padding: EdgeInsets.only(bottom: 20.0),
child: Text(
"Select a few and set their duration.",
style: const TextStyle(color: Colors.white70, fontSize: 17.0),
),
),
SizedBox(
child: Padding(
padding: EdgeInsets.symmetric(horizontal: 25.0),
child: Container(
height: 1.0,
color: Colors.yellowAccent,
),
),
),
//---------------LIST OF EVENTS---------------
Row(
mainAxisAlignment: MainAxisAlignment.start,
children: <Widget>[
Padding(
padding: EdgeInsets.only(left: 50.0, top: 20.0, bottom: 10.0),
child: Text(
"Push UPS",
style: const TextStyle(color: Colors.white, fontSize: 25.0),
),
),
Padding(
padding: EdgeInsets.only(top: 8.0),
child: FlatButton(
onPressed: () {
_selectTime(context);
},
child: new Icon(
Icons.timelapse,
color: Colors.white,
),
),
),
Padding(
padding: EdgeInsets.only(top: 8.0, right: 20.0),
child: Text(
'${_duration.inMinutes.toString()} min',
style: const TextStyle(color: Colors.white, fontSize: 25.0),
),
),
],
),
Row(
mainAxisAlignment: MainAxisAlignment.start,
children: <Widget>[
Padding(
padding: EdgeInsets.only(left: 50.0, top: 20.0, bottom: 10.0),
child: Text(
"Pull UPS",
style: const TextStyle(color: Colors.white, fontSize: 25.0),
),
),
Padding(
padding: EdgeInsets.only(top: 8.0),
child: FlatButton(
onPressed: () {
_selectTime(context);
},
child: new Icon(
Icons.timelapse,
color: Colors.white,
),
),
),
Padding(
padding: EdgeInsets.only(top: 8.0, right: 20.0),
child: Text(
'${_duration.inMinutes.toString()} min',
style: const TextStyle(color: Colors.white, fontSize: 25.0),
),
),
],
),
Row(
mainAxisAlignment: MainAxisAlignment.start,
children: <Widget>[
Padding(
padding: EdgeInsets.only(left: 50.0, top: 20.0, bottom: 10.0),
child: Text(
"What's Today?",
style: const TextStyle(color: Colors.white, fontSize: 25.0),
),
),
Padding(
padding: EdgeInsets.only(top: 8.0),
child: FlatButton(
onPressed: () {
_selectTime(context);
},
child: new Icon(
Icons.timelapse,
color: Colors.white,
),
),
),
Padding(
padding: EdgeInsets.only(top: 8.0, right: 20.0),
child: Text(
'${_duration.inMinutes.toString()} min',
style: const TextStyle(color: Colors.white, fontSize: 25.0),
),
),
],
),
],
),
),
);
}
}
So, I start the app and the initial time is 0 initial time
Then I set the time on the first button setting time
Now it changes the time on all buttons final state
how do I get different times for different buttons?

The problem is that your are using just one variable and when you change that variable all Text widgets get updated with the same value.
You need to use three duration variables, one for each value.
The simplest way is the following:
import 'package:flutter/material.dart';
import 'package:flutter_duration_picker/flutter_duration_picker.dart';
import 'dart:async';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: EndurancePage(),
);
}
}
class EndurancePage extends StatefulWidget {
#override
_EndurancePageState createState() => _EndurancePageState();
}
class _EndurancePageState extends State<EndurancePage> {
Duration _duration1 = Duration();
Duration _duration2 = Duration();
Duration _duration3 = Duration();
Future<Null> _selectTime(BuildContext context, int timer) async {
if (timer == 1) {
final Duration picked =
await showDurationPicker(context: context, initialTime: _duration1);
if (picked != null && picked != _duration1) {
setState(() {
_duration1 = picked;
});
}
} else if (timer == 2) {
final Duration picked =
await showDurationPicker(context: context, initialTime: _duration2);
if (picked != null && picked != _duration2) {
setState(() {
_duration2 = picked;
});
}
} else if (timer == 3) {
final Duration picked =
await showDurationPicker(context: context, initialTime: _duration3);
if (picked != null && picked != _duration3) {
setState(() {
_duration3 = picked;
});
}
}
}
#override
Widget build(BuildContext context) {
return SingleChildScrollView(
child: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Padding(
padding: EdgeInsets.only(top: 100.0, bottom: 30.0),
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text(
"Excer",
textAlign: TextAlign.center,
style:
const TextStyle(fontSize: 35.0, color: Colors.white),
),
Text(
"sices",
textAlign: TextAlign.center,
style: const TextStyle(
fontSize: 35.0,
color: Colors.white,
fontWeight: FontWeight.bold),
),
]),
),
Padding(
padding: EdgeInsets.only(bottom: 20.0),
child: Text(
"Select a few and set their duration.",
style: const TextStyle(color: Colors.white70, fontSize: 17.0),
),
),
SizedBox(
child: Padding(
padding: EdgeInsets.symmetric(horizontal: 25.0),
child: Container(
height: 1.0,
color: Colors.yellowAccent,
),
),
),
//---------------LIST OF EVENTS---------------
Row(
mainAxisAlignment: MainAxisAlignment.start,
children: <Widget>[
Padding(
padding: EdgeInsets.only(left: 50.0, top: 20.0, bottom: 10.0),
child: Text(
"Push UPS",
style: const TextStyle(color: Colors.white, fontSize: 25.0),
),
),
Padding(
padding: EdgeInsets.only(top: 8.0),
child: FlatButton(
onPressed: () {
_selectTime(context, 1);
},
child: new Icon(
Icons.timelapse,
color: Colors.white,
),
),
),
Padding(
padding: EdgeInsets.only(top: 8.0, right: 20.0),
child: Text(
'${_duration1.inMinutes.toString()} min',
style: const TextStyle(color: Colors.white, fontSize: 25.0),
),
),
],
),
Row(
mainAxisAlignment: MainAxisAlignment.start,
children: <Widget>[
Padding(
padding: EdgeInsets.only(left: 50.0, top: 20.0, bottom: 10.0),
child: Text(
"Pull UPS",
style: const TextStyle(color: Colors.white, fontSize: 25.0),
),
),
Padding(
padding: EdgeInsets.only(top: 8.0),
child: FlatButton(
onPressed: () {
_selectTime(context, 2);
},
child: new Icon(
Icons.timelapse,
color: Colors.white,
),
),
),
Padding(
padding: EdgeInsets.only(top: 8.0, right: 20.0),
child: Text(
'${_duration2.inMinutes.toString()} min',
style: const TextStyle(color: Colors.white, fontSize: 25.0),
),
),
],
),
Row(
mainAxisAlignment: MainAxisAlignment.start,
children: <Widget>[
Padding(
padding: EdgeInsets.only(left: 50.0, top: 20.0, bottom: 10.0),
child: Text(
"What's Today?",
style: const TextStyle(color: Colors.white, fontSize: 25.0),
),
),
Padding(
padding: EdgeInsets.only(top: 8.0),
child: FlatButton(
onPressed: () {
_selectTime(context, 3);
},
child: new Icon(
Icons.timelapse,
color: Colors.white,
),
),
),
Padding(
padding: EdgeInsets.only(top: 8.0, right: 20.0),
child: Text(
'${_duration3.inMinutes.toString()} min',
style: const TextStyle(color: Colors.white, fontSize: 25.0),
),
),
],
),
],
),
),
);
}
}
Another option, passing the duration variable as a parameter would be the following:
import 'package:flutter/material.dart';
import 'package:flutter_duration_picker/flutter_duration_picker.dart';
import 'dart:async';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: EndurancePage(),
);
}
}
class EndurancePage extends StatefulWidget {
#override
_EndurancePageState createState() => _EndurancePageState();
}
class _EndurancePageState extends State<EndurancePage> {
Duration _duration1 = Duration();
Duration _duration2 = Duration();
Duration _duration3 = Duration();
Future<Duration> _selectTime(BuildContext context, Duration duration) async {
final Duration picked =
await showDurationPicker(context: context, initialTime: duration);
if (picked != null && picked != duration) {
setState(() {});
return picked;
}
return null;
}
#override
Widget build(BuildContext context) {
return SingleChildScrollView(
child: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Padding(
padding: EdgeInsets.only(top: 100.0, bottom: 30.0),
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text(
"Excer",
textAlign: TextAlign.center,
style:
const TextStyle(fontSize: 35.0, color: Colors.white),
),
Text(
"sices",
textAlign: TextAlign.center,
style: const TextStyle(
fontSize: 35.0,
color: Colors.white,
fontWeight: FontWeight.bold),
),
]),
),
Padding(
padding: EdgeInsets.only(bottom: 20.0),
child: Text(
"Select a few and set their duration.",
style: const TextStyle(color: Colors.white70, fontSize: 17.0),
),
),
SizedBox(
child: Padding(
padding: EdgeInsets.symmetric(horizontal: 25.0),
child: Container(
height: 1.0,
color: Colors.yellowAccent,
),
),
),
//---------------LIST OF EVENTS---------------
Row(
mainAxisAlignment: MainAxisAlignment.start,
children: <Widget>[
Padding(
padding: EdgeInsets.only(left: 50.0, top: 20.0, bottom: 10.0),
child: Text(
"Push UPS",
style: const TextStyle(color: Colors.white, fontSize: 25.0),
),
),
Padding(
padding: EdgeInsets.only(top: 8.0),
child: FlatButton(
onPressed: () async {
_duration1 = await _selectTime(context, _duration1);
},
child: new Icon(
Icons.timelapse,
color: Colors.white,
),
),
),
Padding(
padding: EdgeInsets.only(top: 8.0, right: 20.0),
child: Text(
'${_duration1.inMinutes.toString()} min',
style: const TextStyle(color: Colors.white, fontSize: 25.0),
),
),
],
),
Row(
mainAxisAlignment: MainAxisAlignment.start,
children: <Widget>[
Padding(
padding: EdgeInsets.only(left: 50.0, top: 20.0, bottom: 10.0),
child: Text(
"Pull UPS",
style: const TextStyle(color: Colors.white, fontSize: 25.0),
),
),
Padding(
padding: EdgeInsets.only(top: 8.0),
child: FlatButton(
onPressed: () async {
_duration2 = await _selectTime(context, _duration2);
},
child: new Icon(
Icons.timelapse,
color: Colors.white,
),
),
),
Padding(
padding: EdgeInsets.only(top: 8.0, right: 20.0),
child: Text(
'${_duration2.inMinutes.toString()} min',
style: const TextStyle(color: Colors.white, fontSize: 25.0),
),
),
],
),
Row(
mainAxisAlignment: MainAxisAlignment.start,
children: <Widget>[
Padding(
padding: EdgeInsets.only(left: 50.0, top: 20.0, bottom: 10.0),
child: Text(
"What's Today?",
style: const TextStyle(color: Colors.white, fontSize: 25.0),
),
),
Padding(
padding: EdgeInsets.only(top: 8.0),
child: FlatButton(
onPressed: () async {
_duration3 = await _selectTime(context, _duration3);
},
child: new Icon(
Icons.timelapse,
color: Colors.white,
),
),
),
Padding(
padding: EdgeInsets.only(top: 8.0, right: 20.0),
child: Text(
'${_duration3.inMinutes.toString()} min',
style: const TextStyle(color: Colors.white, fontSize: 25.0),
),
),
],
),
],
),
),
);
}
}

Related

How do I put a button in a block in flutter?

Used expanded, container. Does not work. I tried to put the Elevated Button in Expanded. And all the time that child can't use something else. Most likely, I don't quite understand the structure. I tried to put the Elevated Button in Expanded.
import 'package:percent_indicator/percent_indicator.dart';
import 'package:flutter/material.dart';
void main() {
runApp(const MaterialApp(
debugShowCheckedModeBanner: false,
home: Pomodoro(),
));
}
class Pomodoro extends StatefulWidget {
const Pomodoro({Key? key}) : super(key: key);
#override
State<Pomodoro> createState() => _PomodoroState();
}
class _PomodoroState extends State<Pomodoro> {
double percent = 0;
// ignore: non_constant_identifier_names, unused_field
static int TimeInMinut = 25;
// ignore: non_constant_identifier_names
int TimeInSec = TimeInMinut = 60;
#override
Widget build(BuildContext context) {
return SafeArea(
child: Scaffold(
body: Container(
decoration: const BoxDecoration(
gradient: LinearGradient(
colors: [Color(0xff1542bf), Color(0xff51a8ff)],
begin: FractionalOffset(0.5, 1)),
),
width: double.infinity,
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
const Padding(
padding: EdgeInsets.only(top: 25.0),
child: Text(
'Pomodoro Clock',
style: TextStyle(color: Colors.white, fontSize: 40.0),
),
),
Expanded(
child: SizedBox(
height: 20.0,
width: 50.0,
child: CircularPercentIndicator(
percent: percent,
animation: true,
animateFromLastPercent: true,
radius: 90.0,
lineWidth: 20.0,
progressColor: Colors.white,
center: Text(
'$TimeInMinut',
style: const TextStyle(
color: Colors.white, fontSize: 30.0),
),
),
),
),
Expanded(
child: Container(
width: double.infinity,
decoration: const BoxDecoration(
color: Color.fromARGB(255, 163, 48, 48),
borderRadius: BorderRadius.only(
topRight: Radius.circular(30.0),
topLeft: Radius.circular(30.0)),
),
child: Padding(
padding: const EdgeInsets.only(
top: 30.0, left: 20.0, right: 20.0),
child: Row(
children: [
Expanded(
child: Column(
children: const [
Text(
'Study Time',
style: TextStyle(
fontSize: 30.0,
),
),
SizedBox(
height: 10.0,
),
Text(
'25',
style: TextStyle(
fontSize: 80.0,
),
),
],
),
),
Expanded(
child: Column(
children: const [
Text(
'Pause Timer',
style: TextStyle(
fontSize: 30.0,
),
),
Text(
'5',
style: TextStyle(
fontSize: 80.0,
),
),
Expanded(
child: Padding(
padding: EdgeInsets.symmetric(vertical: 10.0),
child: Text(
'hello',
),
))
],
),
),
],
),
),
),
),
Container(
padding: const EdgeInsets.symmetric(vertical: 0.0),
child: ElevatedButton(
onPressed: () {},
style: ElevatedButton.styleFrom(
backgroundColor: Colors.red,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(100.0),
),
),
child: const Padding(
padding: EdgeInsets.all(20.0),
child: Text(
'start studing',
style: TextStyle(color: Colors.white, fontSize: 22.0),
),
),
),
),
]),
),
),
);
}
}
If you like to use Expanded on Text(hello) widget. You need to get constrains from top level/parent widget, but this is not the solution you like to archive.
I will recommend checking /layout/constraints
As for the answer, you need to wrap Row widget Column to place another child just after the row widget. It could be skipped if you we had same color as background.
import 'package:percent_indicator/percent_indicator.dart';
import 'package:flutter/material.dart';
void main() {
runApp(const MaterialApp(
debugShowCheckedModeBanner: false,
home: Pomodoro(),
));
}
class Pomodoro extends StatefulWidget {
const Pomodoro({Key? key}) : super(key: key);
#override
State<Pomodoro> createState() => _PomodoroState();
}
class _PomodoroState extends State<Pomodoro> {
double percent = 0;
// ignore: non_constant_identifier_names, unused_field
static int TimeInMinut = 25;
// ignore: non_constant_identifier_names
int TimeInSec = TimeInMinut = 60;
#override
Widget build(BuildContext context) {
return SafeArea(
child: Scaffold(
body: Container(
decoration: const BoxDecoration(
gradient: LinearGradient(
colors: [Color(0xff1542bf), Color(0xff51a8ff)],
begin: FractionalOffset(0.5, 1)),
),
width: double.infinity,
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
const Padding(
padding: EdgeInsets.only(top: 25.0),
child: Text(
'Pomodoro Clock',
style: TextStyle(color: Colors.white, fontSize: 40.0),
),
),
Expanded(
child: SizedBox(
height: 20.0,
width: 50.0,
child: CircularPercentIndicator(
percent: percent,
animation: true,
animateFromLastPercent: true,
radius: 90.0,
lineWidth: 20.0,
progressColor: Colors.white,
center: Text(
'$TimeInMinut',
style: const TextStyle(
color: Colors.white, fontSize: 30.0),
),
),
),
),
Expanded(
child: Container(
width: double.infinity,
padding: const EdgeInsets.only(
top: 30.0, left: 20.0, right: 20.0),
decoration: const BoxDecoration(
color: Color.fromARGB(255, 163, 48, 48),
borderRadius: BorderRadius.only(
topRight: Radius.circular(30.0),
topLeft: Radius.circular(30.0)),
),
child: Column(
children: [
Row(
children: [
Expanded(
child: Column(
children: const [
Text(
'Study Time',
style: TextStyle(
fontSize: 30.0,
),
),
SizedBox(
height: 10.0,
),
Text(
'25',
style: TextStyle(
fontSize: 80.0,
),
),
],
),
),
Column(
children: const [
Text(
'Pause Timer',
style: TextStyle(
fontSize: 30.0,
),
),
Text(
'5',
style: TextStyle(
fontSize: 80.0,
),
),
Padding(
padding: EdgeInsets.symmetric(vertical: 10.0),
child: Text(
'hello',
),
)
],
),
],
),
Container(
height: 100,
width: 200,
padding: const EdgeInsets.symmetric(vertical: 0.0),
child: ElevatedButton(
onPressed: () {},
style: ElevatedButton.styleFrom(
backgroundColor: Colors.red,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(100.0),
),
),
child: const Padding(
padding: EdgeInsets.all(20.0),
child: Text(
'start studing',
style: TextStyle(
color: Colors.white, fontSize: 22.0),
),
),
),
),
],
),
),
),
]),
),
),
);
}
}

Widget buildRow not appearing

I am working on one of the screens of my app, my first widget buildrow shows up perfectly however the second one does not appear, is this because my screen is not wide enough? I do have 3 buttons within the first buildrow, does that mean it will not show up because it is below it? Here is my code! Please let me know if anyone can help!
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.task.name),
),
body: Material(
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: <Widget>[
Expanded(
child: timerText,
),
Expanded(
flex: 0,
child: Padding(
padding: const EdgeInsets.only(bottom: 24.0),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: <Widget>[
RaisedButton(
onPressed: disable
? null
: () {
setState(() {
StudyViewModel.stopwatch.reset();
});
},
color: Colors.red,
padding: EdgeInsets.symmetric(
horizontal: 60.0,
vertical: 20.0,
),
child: Text(
"Reset",
style: TextStyle(fontSize: 20.0, color: Colors.white),
),
),
RaisedButton(
onPressed: () {
setState(() {
if (StudyViewModel.stopwatch.isRunning) {
StudyViewModel.stopwatch.stop();
disable = false;
} else {
StudyViewModel.stopwatch.start();
disable = true;
}
});
},
color: Colors.green,
padding: EdgeInsets.symmetric(
horizontal: 60.0,
vertical: 20.0,
),
child: Text(
"Play/Pause",
style: TextStyle(fontSize: 24.0, color: Colors.white),
),
),
RaisedButton(
onPressed: disable
? null
: () async {
widget.task.elapsedTime =
StudyViewModel.milliToElapsedString(
StudyViewModel
.stopwatch.elapsedMilliseconds);
await StudyViewModel.saveFile();
Navigator.of(context).pop();
},
color: Colors.yellow,
padding: EdgeInsets.symmetric(
horizontal: 60.0,
vertical: 20.0,
),
child: Text(
"Save",
style: TextStyle(fontSize: 24.0, color: Colors.white),
),
),
],
),
),
),
],
),
),
);
}
Widget buildRow(BuildContext context, int index) {
return ListView(
children: <Widget>[
Text(StudyViewModel.studies[index].name,
style: TextStyle(fontSize: 18.0),
),
ListView.builder(
shrinkWrap: true,
primary: false,
itemCount: StudyViewModel.studies[index].tasks.length,
itemBuilder: (context, int taskIndex) {
return ListTile(
title: Text(StudyViewModel.studies[index].tasks[taskIndex].name),
contentPadding: EdgeInsets.symmetric(horizontal: 32.0),
subtitle: Text(
StudyViewModel.studies[index].tasks[taskIndex].elapsedTime),
);
},
),
],
);
}
}
Try to wrap your middle RaisedButton with Flexible.
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.task.name),
),
body: Material(
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: <Widget>[
Expanded(
child: timerText,
),
Expanded(
flex: 0,
child: Padding(
padding: const EdgeInsets.only(bottom: 24.0),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: <Widget>[
RaisedButton(
onPressed: disable
? null
: () {
setState(() {
StudyViewModel.stopwatch.reset();
});
},
color: Colors.red,
padding: EdgeInsets.symmetric(
horizontal: 60.0,
vertical: 20.0,
),
child: Text(
"Reset",
style: TextStyle(fontSize: 20.0, color: Colors.white),
),
),
Flexible(
child: RaisedButton(
onPressed: () {
setState(() {
if (StudyViewModel.stopwatch.isRunning) {
StudyViewModel.stopwatch.stop();
disable = false;
} else {
StudyViewModel.stopwatch.start();
disable = true;
}
});
},
color: Colors.green,
padding: EdgeInsets.symmetric(
horizontal: 60.0,
vertical: 20.0,
),
child: Text(
"Play/Pause",
style: TextStyle(fontSize: 24.0, color: Colors.white),
),
),
),
RaisedButton(
onPressed: disable
? null
: () async {
widget.task.elapsedTime =
StudyViewModel.milliToElapsedString(
StudyViewModel
.stopwatch.elapsedMilliseconds);
await StudyViewModel.saveFile();
Navigator.of(context).pop();
},
color: Colors.yellow,
padding: EdgeInsets.symmetric(
horizontal: 60.0,
vertical: 20.0,
),
child: Text(
"Save",
style: TextStyle(fontSize: 24.0, color: Colors.white),
),
),
],
),
),
),
],
),
),
);
}

Flutter: Updating UI from outside of a StatefulWidget

I am new to flutter, and working on a shopping cart project. i don't know how exatly i am suppose to ask this question but, here is what i wanted.
I am trying to update my UI when the cart item and prices changes, which means to display sum amount of products from ListView (Stateful widget) to main OrderPage Stateful widget. I know about setState() method, but i think i should use some callback methods here, dont know exactly.
I have explained in short in Image - see below img
What i have done: when user modify cart products, I have saved the value (price/product/count) in to constant value , i calculate the value and save in constant value, and later use that const var in Main widget (Main Ui), which does update when i close and reopen the page, but could not able to update when button pressed (product +/-buttons)
What i want to do is,
Update my total value when +/- buttons are pressed.
Here is my full code:
class cartConstant{
static int packageCount;
static List<int> list;
}
class OrderPage extends StatefulWidget {
#override
_OrderPageState createState() => _OrderPageState();
}
class _OrderPageState extends State<OrderPage> {
int data = 3;
#override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.white,
appBar: AppBar(
automaticallyImplyLeading: true,
iconTheme: IconThemeData(
color: Colors.black54, //change your color here
),
backgroundColor: Colors.white,
elevation: 1,
title: Text("Your order Summery",style: TextStyle(color: Colors.black54),),
centerTitle: true,
),
body: Container(
child:
FutureBuilder(
builder: (context, snapshot){
// var datas = snapshot.data;
return
ListView.builder(
physics: ClampingScrollPhysics(),
shrinkWrap: true,
itemCount: data,
itemBuilder: (BuildContext context, int index){
// Cart cart = datas[index];
return CartListView();
},
padding: EdgeInsets.symmetric(horizontal: 10.0),
scrollDirection: Axis.vertical,
);
},
),
),
bottomNavigationBar: _buildTotalContainer(),
);
}
Widget _buildTotalContainer() {
return Container(
height: 220.0,
padding: EdgeInsets.only(
left: 10.0,
right: 10.0,
),
child: Column(
children: <Widget>[
SizedBox(
height: 10.0,
),
Padding(
padding: const EdgeInsets.only(top: 10),
child: Row(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
Text(
"Subtotal",
style: TextStyle(
color: Color(0xFF9BA7C6),
fontSize: 16.0,
fontWeight: FontWeight.bold),
),
Text(
cartConstant.packageCount.toString(),
style: TextStyle(
color: Color(0xFF6C6D6D),
fontSize: 16.0,
fontWeight: FontWeight.bold),
),
],
),
),
SizedBox(
height: 15,
),
Row(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
Text(
"Discount",
style: TextStyle(
color: Color(0xFF9BA7C6),
fontSize: 16.0,
fontWeight: FontWeight.bold),
),
Text(
"0.0",
style: TextStyle(
color: Color(0xFF6C6D6D),
fontSize: 16.0,
fontWeight: FontWeight.bold),
),
],
),
SizedBox(
height: 10.0,
),
Divider(
height: 2.0,
),
SizedBox(
height: 20.0,
),
Row(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
Text(
"Cart Total",
style: TextStyle(
color: Color(0xFF9BA7C6),
fontSize: 16.0,
fontWeight: FontWeight.bold),
),
Text(
cartConstant.packageCount.toString(),
style: TextStyle(
color: Color(0xFF6C6D6D),
fontSize: 16.0,
fontWeight: FontWeight.bold),
),
],
),
SizedBox(
height: 20.0,
),
GestureDetector(
onTap: () {
// Navigator.of(context).push(MaterialPageRoute(builder: (BuildContext context) => SignInPage()));
},
child: Container(
height: 50.0,
decoration: BoxDecoration(
color: Colors.red,
borderRadius: BorderRadius.circular(35.0),
),
child: Center(
child: Text(
"Proceed To Checkout",
style: TextStyle(
color: Colors.white,
fontSize: 18.0,
fontWeight: FontWeight.bold,
),
),
),
),
),
SizedBox(
height: 20.0,
),
],
),
);
}
}
class CartListView extends StatefulWidget {
#override
_CartListViewState createState() => _CartListViewState();
}
class _CartListViewState extends State<CartListView> {
int _counter = 1;
int getPrice(int i,int priceC){
cartConstant.packageCount = i*priceC;
return cartConstant.packageCount;
}
#override
Widget build(BuildContext context) {
return Card(
child: Padding(
padding: EdgeInsets.symmetric(horizontal: 15.0, vertical: 15.0),
child: Row(
mainAxisSize: MainAxisSize.max,
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Container(
decoration: BoxDecoration(
border: Border.all(color: Color(0xFFD3D3D3), width: 2.0),
borderRadius: BorderRadius.circular(10.0),
),
child: Padding(
padding: EdgeInsets.symmetric(
horizontal: 10.0,
),
child: Column(
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
InkWell(
onTap: (){
setState(() {
_counter++;
if (_counter > 20) {
_counter = 20;
}
});
},
child: Icon(Icons.add, color: Color(0xFFD3D3D3))),
Text(
"$_counter",
style: TextStyle(fontSize: 18.0, color: Colors.grey),
),
InkWell(
onTap:(){
setState(() {
_counter--;
if (_counter < 2) {
_counter = 1;
}
});
},
child: Icon(Icons.remove, color: Color(0xFFD3D3D3))),
],
),
),
),
SizedBox(
width: 20.0,
),
Container(
height: 70.0,
width: 70.0,
decoration: BoxDecoration(
image: DecorationImage(
image: AssetImage("assets/images/food.jpg"),
fit: BoxFit.cover),
borderRadius: BorderRadius.circular(35.0),
boxShadow: [
BoxShadow(
color: Colors.black54,
blurRadius: 5.0,
offset: Offset(0.0, 2.0))
]),
),
SizedBox(
width: 20.0,
),
Column(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Text(
"Employee Package",
style: TextStyle(fontSize: 16.0, fontWeight: FontWeight.bold),
),
SizedBox(height: 5.0),
SizedBox(height: 5.0),
Container(
height: 25.0,
width: 120.0,
child: ListView(
scrollDirection: Axis.horizontal,
children: <Widget>[
Row(
children: <Widget>[
Text("Price",
style: TextStyle(
color: Color(0xFFD3D3D3),
fontWeight: FontWeight.bold)),
SizedBox(
width: 5.0,
),
InkWell(
onTap: () {},
child: Text(
getPrice(_counter, 2000).toString(),
style: TextStyle(
fontWeight: FontWeight.bold,
color: Colors.red,
),
),
),
SizedBox(
width: 10.0,
),
],
),
],
),
),
],
),
Spacer(),
GestureDetector(
onTap: () {
},
child: Icon(
Icons.cancel,
color: Colors.grey,
),
),
],
),
),
);
}
}
you can also check from my cart screen shot below:
You can copy paste run full code below
You can use callback refresh() and pass callback to CartListView
code snippet
class _OrderPageState extends State<OrderPage> {
int data = 3;
void refresh() {
setState(() {});
}
...
itemBuilder: (BuildContext context, int index) {
// Cart cart = datas[index];
return CartListView(refresh);
},
...
class CartListView extends StatefulWidget {
VoidCallback callback;
CartListView(this.callback);
...
InkWell(
onTap: () {
setState(() {
_counter++;
if (_counter > 20) {
_counter = 20;
}
});
widget.callback();
},
working demo
full code
import 'package:flutter/material.dart';
class cartConstant {
static int packageCount;
static List<int> list;
}
class OrderPage extends StatefulWidget {
#override
_OrderPageState createState() => _OrderPageState();
}
class _OrderPageState extends State<OrderPage> {
int data = 3;
void refresh() {
setState(() {});
}
#override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.white,
appBar: AppBar(
automaticallyImplyLeading: true,
iconTheme: IconThemeData(
color: Colors.black54, //change your color here
),
backgroundColor: Colors.white,
elevation: 1,
title: Text(
"Your order Summery",
style: TextStyle(color: Colors.black54),
),
centerTitle: true,
),
body: Container(
child: FutureBuilder(
builder: (context, snapshot) {
// var datas = snapshot.data;
return ListView.builder(
physics: ClampingScrollPhysics(),
shrinkWrap: true,
itemCount: data,
itemBuilder: (BuildContext context, int index) {
// Cart cart = datas[index];
return CartListView(refresh);
},
padding: EdgeInsets.symmetric(horizontal: 10.0),
scrollDirection: Axis.vertical,
);
},
),
),
bottomNavigationBar: _buildTotalContainer(),
);
}
Widget _buildTotalContainer() {
return Container(
height: 220.0,
padding: EdgeInsets.only(
left: 10.0,
right: 10.0,
),
child: Column(
children: <Widget>[
SizedBox(
height: 10.0,
),
Padding(
padding: const EdgeInsets.only(top: 10),
child: Row(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
Text(
"Subtotal",
style: TextStyle(
color: Color(0xFF9BA7C6),
fontSize: 16.0,
fontWeight: FontWeight.bold),
),
Text(
cartConstant.packageCount.toString(),
style: TextStyle(
color: Color(0xFF6C6D6D),
fontSize: 16.0,
fontWeight: FontWeight.bold),
),
],
),
),
SizedBox(
height: 15,
),
Row(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
Text(
"Discount",
style: TextStyle(
color: Color(0xFF9BA7C6),
fontSize: 16.0,
fontWeight: FontWeight.bold),
),
Text(
"0.0",
style: TextStyle(
color: Color(0xFF6C6D6D),
fontSize: 16.0,
fontWeight: FontWeight.bold),
),
],
),
SizedBox(
height: 10.0,
),
Divider(
height: 2.0,
),
SizedBox(
height: 20.0,
),
Row(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
Text(
"Cart Total",
style: TextStyle(
color: Color(0xFF9BA7C6),
fontSize: 16.0,
fontWeight: FontWeight.bold),
),
Text(
"8000",
style: TextStyle(
color: Color(0xFF6C6D6D),
fontSize: 16.0,
fontWeight: FontWeight.bold),
),
],
),
SizedBox(
height: 20.0,
),
GestureDetector(
onTap: () {
// Navigator.of(context).push(MaterialPageRoute(builder: (BuildContext context) => SignInPage()));
},
child: Container(
height: 50.0,
decoration: BoxDecoration(
color: Colors.red,
borderRadius: BorderRadius.circular(35.0),
),
child: Center(
child: Text(
"Proceed To Checkout",
style: TextStyle(
color: Colors.white,
fontSize: 18.0,
fontWeight: FontWeight.bold,
),
),
),
),
),
SizedBox(
height: 20.0,
),
],
),
);
}
}
class CartListView extends StatefulWidget {
VoidCallback callback;
CartListView(this.callback);
#override
_CartListViewState createState() => _CartListViewState();
}
class _CartListViewState extends State<CartListView> {
int _counter = 1;
int getPrice(int i, int priceC) {
cartConstant.packageCount = i * priceC;
return cartConstant.packageCount;
}
#override
Widget build(BuildContext context) {
return Card(
child: Padding(
padding: EdgeInsets.symmetric(horizontal: 15.0, vertical: 15.0),
child: Row(
mainAxisSize: MainAxisSize.max,
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Container(
decoration: BoxDecoration(
border: Border.all(color: Color(0xFFD3D3D3), width: 2.0),
borderRadius: BorderRadius.circular(10.0),
),
child: Padding(
padding: EdgeInsets.symmetric(
horizontal: 10.0,
),
child: Column(
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
InkWell(
onTap: () {
setState(() {
_counter++;
if (_counter > 20) {
_counter = 20;
}
});
widget.callback();
},
child: Icon(Icons.add, color: Color(0xFFD3D3D3))),
Text(
"$_counter",
style: TextStyle(fontSize: 18.0, color: Colors.grey),
),
InkWell(
onTap: () {
setState(() {
_counter--;
if (_counter < 2) {
_counter = 1;
}
});
widget.callback();
},
child: Icon(Icons.remove, color: Color(0xFFD3D3D3))),
],
),
),
),
SizedBox(
width: 20.0,
),
Container(
height: 70.0,
width: 70.0,
decoration: BoxDecoration(
image: DecorationImage(
image: AssetImage("assets/images/food.jpg"),
fit: BoxFit.cover),
borderRadius: BorderRadius.circular(35.0),
boxShadow: [
BoxShadow(
color: Colors.black54,
blurRadius: 5.0,
offset: Offset(0.0, 2.0))
]),
),
SizedBox(
width: 20.0,
),
Column(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Text(
"Employee Package",
style: TextStyle(fontSize: 16.0, fontWeight: FontWeight.bold),
),
SizedBox(height: 5.0),
SizedBox(height: 5.0),
Container(
height: 25.0,
width: 120.0,
child: ListView(
scrollDirection: Axis.horizontal,
children: <Widget>[
Row(
children: <Widget>[
Text("Price",
style: TextStyle(
color: Color(0xFFD3D3D3),
fontWeight: FontWeight.bold)),
SizedBox(
width: 5.0,
),
InkWell(
onTap: () {},
child: Text(
getPrice(_counter, 2000).toString(),
style: TextStyle(
fontWeight: FontWeight.bold,
color: Colors.red,
),
),
),
SizedBox(
width: 10.0,
),
],
),
],
),
),
],
),
Spacer(),
GestureDetector(
onTap: () {},
child: Icon(
Icons.cancel,
color: Colors.grey,
),
),
],
),
),
);
}
}
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
visualDensity: VisualDensity.adaptivePlatformDensity,
),
home: OrderPage(),
);
}
}
When the button is tapped, you just need to update the Subtotal amount and cart total.
Step 1 : Replace the harcoded value by a variable. So, something like :
Row(
children: <Widget>[
Text(
"Subtotal",
style: ...
),
Text(
"$subTotal",
style: ....
),
],
),
Step 2 : Now, add a code to calcualte subTotal and cartTotal. You already have code which increments and decrements the variable _counter. You just need to tweak that part like :
setState( (){
_counter++;
// So, the quantity is increased. Just get the price of current item and add in the sub total.
subTotal += priceC;
cartTotal = subTotal - discount;
} );

Countdown timer in flutter

I want to make a flutter countdown timer to display remaining registration time (DD-HH-MM).
Example:
What would be the most efficient way of accomplishing this?
Thank you
Change below code as your design and requirement
DateTime startTime = DateTime(2020,03,04);
Duration remaining = DateTime.now().difference(DateTime.now());
Timer t;
int days=0,hrs =0, mins=0;
#override
void initState(){
super.initState();
startTimer();
}
startTimer()async{
t = Timer.periodic(Duration(seconds:1),(timer){
setState((){
remaining = DateTime.now().difference(startTime);
mins = remaining.inMinutes;
hrs = mins>=60 ? mins~/60:0;
days = hrs>=24 ? hrs~/24: 0;
hrs = hrs%24;
mins = mins%60;
});
});
}
#override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.white,
body: Center(
child: Column(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
Padding(
padding: const EdgeInsets.all(8.0),
child: Text('Registration closes in',
style: TextStyle(color: Colors.black, fontSize: 20),
textAlign: TextAlign.center),
),
Row(
mainAxisAlignment:MainAxisAlignment.spaceEvenly,
children: [
Expanded(
child: Padding(
padding: const EdgeInsets.all(8.0),
child: Text('$days',
style: TextStyle(color: Colors.black, fontSize: 20),
textAlign:TextAlign.center,),
),
),
Expanded(
child: Padding(
padding: const EdgeInsets.all(8.0),
child: Text('$hrs',
style: TextStyle(color: Colors.black, fontSize: 20),
textAlign:TextAlign.center,),
),
),
Expanded(
child: Padding(
padding: const EdgeInsets.all(8.0),
child: Text('$mins',
style: TextStyle(color: Colors.black, fontSize: 20),
textAlign:TextAlign.center,),
),
),
]),
Row(
mainAxisAlignment:MainAxisAlignment.spaceEvenly,
children: [
Expanded(
child: Padding(
padding: const EdgeInsets.all(8.0),
child: Text('Days',
style: TextStyle(color: Colors.black, fontSize: 16),
textAlign:TextAlign.center,),
),
),
Expanded(
child: Padding(
padding: const EdgeInsets.all(8.0),
child: Text('Hours',
style: TextStyle(color: Colors.black, fontSize: 16),
textAlign:TextAlign.center,),
),
),
Expanded(
child: Padding(
padding: const EdgeInsets.all(8.0),
child: Text('Minutes',
style: TextStyle(color: Colors.black, fontSize: 16),
textAlign:TextAlign.center,),
),
),
]),
],
)));
}

"'borderRadius != null I/flutter (28205): || clipper != null': is not true" why am i getting this error?

I am trying to fetch data from an api and just show it in my list of cards. But whenever i load the app i get this error
'borderRadius != null
I/flutter (28205): || clipper != null': is not true.
and i not sure how to solve this.
I have tried making changes in the line the error has occurred but the error remains the same.
import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:news/model/businessModel.dart';
import 'package:http/http.dart' as http;
class Discover extends StatefulWidget {
final Source source;
Discover({Key key, this.source}) : super(key: key);
#override
_DiscoverState createState() => _DiscoverState();
}
class _DiscoverState extends State<Discover> {
String API_KEY = '0ca85f22bce44565ba4fee8d2224adb5';
Future<List<Articles>> fetchArticleBySource() async {
final response = await http.get(
'https://newsapi.org/v2/top-headlines?
category=business&language=en&apiKey=${API_KEY}');
if (response.statusCode == 200) {
List articles = json.decode(response.body)['articles'];
return articles.map((article) => new
Articles.fromJson(article)).toList();
} else {
throw Exception('Failed to load article list');
}
}
var list_articles;
var refreshKey = GlobalKey<RefreshIndicatorState>();
#override
void initState() {
// TODO: implement initState
super.initState();
refreshListArticle();
}
Future<Null> refreshListArticle() async {
refreshKey.currentState?.show(atTop: false);
setState(() {
list_articles = fetchArticleBySource();
});
}
#override
Widget build(BuildContext context) {
return Padding(
padding: const EdgeInsets.only(
left: 15.0,
top: 15.0,
right: 15.0,
),
child: ListView(
children: <Widget>[
topArea(),
SizedBox(
height: 10.0,
),
slideCard(),
SizedBox(
height: 5.0,
),
Padding(
padding: const EdgeInsets.only(left: 4.0),
child: Divider(),
),
recentNews(),
],
),
);
}
Widget topArea() {
return Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Text(
"WEDNESDAY, NOVEMBER 29",
style: TextStyle(color: Colors.grey, fontWeight:
FontWeight.bold),
),
SizedBox(
height: 5.0,
),
Text(
"TOP NEWS",
style: TextStyle(fontSize: 25.0, fontWeight: FontWeight.bold),
),
],
),
Hero(
tag: 'img',
child: InkWell(
//onTap: () => Navigator.push(context, MaterialPageRoute(builder:
(context) => )),
child: CircleAvatar(
radius: 25.0,
//backgroundColor: Colors.transparent,
backgroundImage: NetworkImage(
"https://images.pexels.com/photos/1138409/pexels-photo-
1138409.jpeg?auto=compress&cs=tinysrgb&dpr=2&h=750&w=1260",
),
),
),
),
],
);
}
Widget slideCard() {
return FutureBuilder<List<Articles>>(
future: list_articles,
builder: (context, snapshot) {
if (snapshot.hasError) {
return Text("${snapshot.error}");
} else if (snapshot.hasData) {
List<Articles> articles = snapshot.data;
return Container(
height: 310.0,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(0.0),
),
child: ListView(
scrollDirection: Axis.horizontal,
children: articles
.map((article) => GestureDetector(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Expanded(
child: Card(
elevation: 3.0,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(10.0),
),
child: ClipRRect(
clipper: ,
child: article.urlToImage != null
? Image.network(article.urlToImage)
: Image.asset('images/logo.jpg'),
),
),
),
SizedBox(
height: 10.0,
),
Padding(
padding: const EdgeInsets.only(left: 4.0),
child: Text("${article.title}",
style: TextStyle(
color: Colors.blueAccent,
fontSize: 12.0,
fontWeight: FontWeight.bold),
),
),
SizedBox(
height: 10.0,
),
Padding(
padding: const EdgeInsets.only(left: 4.0),
child: Text(
"${article.description}",
style: TextStyle(
color: Colors.black,
fontSize: 14.0,
fontWeight: FontWeight.bold),
),
),
],
),
))
.toList(),
),
);
}
return CircularProgressIndicator();
},
);
}
Widget recentNews() {
return Column(
children: <Widget>[
Padding(
padding: const EdgeInsets.only(left: 4.0),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
Text(
"Recent News",
style: TextStyle(fontSize: 20.0, fontWeight: FontWeight.bold),
),
Align(
alignment: Alignment.centerRight,
child: Text(
"See All",
style: TextStyle(color: Colors.lightBlueAccent),
),
)
],
),
),
SizedBox(
height: 7.0,
),
Container(
height: 200.0,
child: ListView(
scrollDirection: Axis.horizontal,
children: <Widget>[
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Expanded(
child: Card(
elevation: 3.0,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(10.0),
),
child: ClipRRect(
child: Image.network(
"https://images.pexels.com/photos/935789/pexels-photo-935789.jpeg?auto=compress&cs=tinysrgb&dpr=2&h=750&w=1260"),
borderRadius: BorderRadius.circular(10.0),
),
),
),
SizedBox(
height: 10.0,
),
Padding(
padding: const EdgeInsets.only(left: 4.0),
child: Text(
"STARTUPS",
style: TextStyle(
color: Colors.blueAccent,
fontSize: 12.0,
fontWeight: FontWeight.bold),
),
),
SizedBox(
height: 10.0,
),
Padding(
padding: const EdgeInsets.only(left: 4.0),
child: Text(
"Top startups that are \nchanging the way we travel",
style: TextStyle(
color: Colors.black,
fontSize: 15.0,
fontWeight: FontWeight.bold),
),
),
],
),
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Expanded(
child: Card(
elevation: 3.0,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(10.0),
),
child: ClipRRect(
child: Image.network(
"https://images.pexels.com/photos/935789/pexels-photo-935789.jpeg?auto=compress&cs=tinysrgb&dpr=2&h=750&w=1260"),
borderRadius: BorderRadius.circular(10.0),
),
),
),
SizedBox(
height: 10.0,
),
Padding(
padding: const EdgeInsets.only(left: 4.0),
child: Text(
"STARTUPS",
style: TextStyle(
color: Colors.blueAccent,
fontSize: 12.0,
fontWeight: FontWeight.bold),
),
),
SizedBox(
height: 10.0,
),
Padding(
padding: const EdgeInsets.only(left: 4.0),
child: Text(
"Top startups that are \nchanging the way we travel",
style: TextStyle(
color: Colors.black,
fontSize: 15.0,
fontWeight: FontWeight.bold),
),
),
],
),
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Expanded(
child: Card(
elevation: 3.0,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(10.0),
),
child: ClipRRect(
child: Image.network(
"https://images.pexels.com/photos/935789/pexels-photo-935789.jpeg?auto=compress&cs=tinysrgb&dpr=2&h=750&w=1260"),
borderRadius: BorderRadius.circular(10.0),
),
),
),
SizedBox(
height: 10.0,
),
Padding(
padding: const EdgeInsets.only(left: 4.0),
child: Text(
"STARTUPS",
style: TextStyle(
color: Colors.blueAccent,
fontSize: 12.0,
fontWeight: FontWeight.bold),
),
),
SizedBox(
height: 10.0,
),
Padding(
padding: const EdgeInsets.only(left: 4.0),
child: Text(
"Top startups that are \nchanging the way we travel",
style: TextStyle(
color: Colors.black,
fontSize: 15.0,
fontWeight: FontWeight.bold),
),
),
],
),
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Expanded(
child: Card(
elevation: 3.0,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(10.0),
),
child: ClipRRect(
child: Image.network(
"https://images.pexels.com/photos/935789/pexels-photo-935789.jpeg?auto=compress&cs=tinysrgb&dpr=2&h=750&w=1260"),
borderRadius: BorderRadius.circular(10.0),
),
),
),
SizedBox(
height: 10.0,
),
Padding(
padding: const EdgeInsets.only(left: 4.0),
child: Text(
"STARTUPS",
style: TextStyle(
color: Colors.blueAccent,
fontSize: 12.0,
fontWeight: FontWeight.bold),
),
),
SizedBox(
height: 10.0,
),
Padding(
padding: const EdgeInsets.only(left: 4.0),
child: Text(
"Top startups that are\n changing the way we travel",
style: TextStyle(
color: Colors.black,
fontSize: 15.0,
fontWeight: FontWeight.bold),
),
),
],
),
],
),
),
],
);
}
}
If you look closely, you will see one ClipRRect whose clipper is empty, thus null.
According to the error message, if the clipper is null, then you have to specify a borderRadius.
child: ClipRRect(
clipper: ,
child: article.urlToImage != null
? Image.network(article.urlToImage)
: Image.asset('images/logo.jpg'),
),