So this is the main code where I fetch the data from json and update my UI.
I have placed" //Area of Interest " comments where the code related to the problem lies.
class MainScreen extends StatefulWidget {
final curLocdata;
MainScreen({this.curLocdata});
#override
_MainScreenState createState() => _MainScreenState();
}
class _MainScreenState extends State<MainScreen> {
Weather weather = Weather();
var cityName;
int temp;
int temp_min;
int temp_max;
Icon weatherIcon;
//Area of Interest 1
RotateAnimatedTextKit textSum;//created a widget of RotateAnimatedTextKit library.
String st;
//Area of Interest 2
#override
void initState() {
// TODO: implement initState
super.initState();
updateUI(widget.curLocdata);//calling update function to rebuild my UI state with new data
}
void updateUI(data) {
setState(() {
if (data == null) {
temp = 0;
cityName = 'Error';
weatherIcon = Icon(Icons.error);
return;
}
cityName = data['name'];
temp = data['main']['temp'].toInt();
temp_min = data['main']['temp_min'].toInt();
temp_max = data['main']['temp_max'].toInt();
var condition = data['weather'][0]['id'];
weatherIcon = weather.getIcon(condition);
textSum = weather.getMessage(temp);//Area of Interest 3
st = weather.subtext(condition);
});
}
#override
Widget build(BuildContext context) {
return Scaffold(
body: Container(
child: SafeArea(
child: Column(
children: <Widget>[
Container(
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
FlatButton(
onPressed: () async {
updateUI(await Network().getData());
},
child: Icon(
FontAwesomeIcons.locationArrow,
),
),
SizedBox(
width: 180.0,
child: TextLiquidFill(
waveDuration: Duration(seconds: 3),
loadDuration: Duration(seconds: 10),
text: 'OpenWeather',
waveColor: Colors.red,
boxBackgroundColor: Color(0xFF1B1B1D),
textStyle: TextStyle(
fontSize: 30.0,
fontWeight: FontWeight.bold,
fontFamily: 'Source Sans Pro',
),
boxHeight: 50.0,
),
),
FlatButton(
onPressed: () async {
String SName = await Navigator.push(context,
MaterialPageRoute(builder: (context) {
return Search();
}));
if (SName != null) {
updateUI(await Network().getDataName(
SName));
}
},
child: Icon(
Icons.add,
color: Colors.white,
size: 40,
),
),
],
),
),
Padding(
padding: EdgeInsets.fromLTRB(50, 50, 50, 0),
child: Row(
children: <Widget>[
SizedBox(
// margin: EdgeInsets.fromLTRB(0, 50, 260, 0),
child: TypewriterAnimatedTextKit(
totalRepeatCount: 200,
isRepeatingAnimation: true,
speed: Duration(milliseconds: 700),
text: [cityName,],
textAlign: TextAlign.left,
textStyle: TextStyle(
fontSize: 20,
fontFamily: 'Source Sans Pro',
),
),
),
],
)),
Expanded(
flex: 9,
child: Container(
margin: EdgeInsets.fromLTRB(50, 30, 50, 80),
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
//mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: <Widget>[
Expanded(
flex: 2,
child: Padding(
padding: EdgeInsets.only(left: 20),
child: Text(
'$temp°',
style: TextStyle(
fontSize: 80,
fontWeight: FontWeight.bold,
fontFamily: 'Source Sans Pro',
),
),
),
),
Expanded(
flex: 2,
child: Padding(
padding: EdgeInsets.only(left: 20),
child: Text(
st,
style: TextStyle(
fontSize: 30,
fontFamily: 'Source Sans Pro',
color: Colors.grey[500]),
),
),
),
Padding(
padding: EdgeInsets.fromLTRB(20, 0, 0, 50),
child: Container(
child: textSum,//Used this textSum to show my animated text. problem
Area of Interest 4
),
),
Expanded(
child: SizedBox(
//width: double.infinity,
//height: 100,
child: Divider(
color: Colors.red,
),
),
),
Row(
children: <Widget>[
Expanded(
child: Padding(
padding: EdgeInsets.fromLTRB(20, 0, 0, 38),
child: Text(
'$temp_min° - $temp_max°',
style: TextStyle(
fontSize: 20,
color: Colors.grey[500],
fontFamily: 'Source Sans Pro',
),
),
),
),
Expanded(
child: Padding(
padding: EdgeInsets.fromLTRB(20, 0, 0, 20),
//padding: const EdgeInsets.all(8.0),
child: AvatarGlow(
endRadius: 30.0, //required
child: Material(
//required
elevation: 0.0,
shape: CircleBorder(),
child: CircleAvatar(
//backgroundColor: Colors.grey[100],
child: weatherIcon
// radius: 40.0,
//shape: BoxShape.circle
),
),
),
),
)
],
)`enter code here`
],
),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(10),
color: Color(0xFF0C0C0C),
),
),
),
Now the weather.dart file from where I am returning RotateAnimatedTextKit widget depending upon the condition
class Weather{
//This return RotateAnimatedTextKit which is then held by textSum and is put as a child inside a container in MainScreen
RotateAnimatedTextKit getMessage(int temp) {
if (temp > 25) {
return RotateAnimatedTextKit(
isRepeatingAnimation: true,
totalRepeatCount: 200,
transitionHeight: 40,
text: ['It\'s 🍦','time and','drink plenty','of water'],
textStyle: TextStyle(fontSize: 30.0, fontFamily: "Source Sans Pro", color: Colors.red),
textAlign: TextAlign.start,
alignment: AlignmentDirectional.topStart // or Alignment.topLeft
);
} else if (temp > 20) {
return RotateAnimatedTextKit(
isRepeatingAnimation: true,
totalRepeatCount: 200,
transitionHeight: 50,
text: ['Time for','shorts','👕','but keep','some warm','clothes handy'],
textStyle: TextStyle(fontSize: 30.0, fontFamily: "Source Sans Pro", color: Colors.red),
textAlign: TextAlign.start,
alignment: AlignmentDirectional.bottomStart// or Alignment.topLeft
);
} else if (temp < 10) {
return RotateAnimatedTextKit(
isRepeatingAnimation: true,
totalRepeatCount: 200,
transitionHeight: 50,
text: ['You\'ll need','a 🧣','and','a 🧤','and a hot', 'soup and turkey'],
textStyle: TextStyle(fontSize: 30.0, fontFamily: "Source Sans Pro", color: Colors.red),
textAlign: TextAlign.start,
alignment: AlignmentDirectional.bottomStart // or Alignment.topLeft
);
} else {
return RotateAnimatedTextKit(
isRepeatingAnimation: true,
transitionHeight: 50,
totalRepeatCount: 200,
text: ['Bring a','🧥','just in case','and also avoid', 'cold breeze','and cold drinks'],
textStyle: TextStyle(fontSize: 30.0, fontFamily: "Source Sans Pro", color: Colors.red),
textAlign: TextAlign.start,
alignment: AlignmentDirectional.bottomStart // or Alignment.topLeft
);
}
}
The thing is that the UI doesn't get updated even when the conditions are different. So any Solutions to why the widget tree is not updating? But it runs only the default text. Also, the cityName which is under the TextLiquidFill doesn't get updated.
Short answer:
Use Keys
Example:
import 'package:animated_text_kit/animated_text_kit.dart';
import 'package:flutter/material.dart';
class MyAnimatedText extends StatefulWidget {
const MyAnimatedText({Key? key}) : super(key: key);
#override
State<MyAnimatedText> createState() => _MyAnimatedTextState();
}
class _MyAnimatedTextState extends State<MyAnimatedText> {
bool isDarkMode = true;
#override
Widget build(BuildContext context) {
return Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(30),
color: isDarkMode ? Colors.grey[850] : Colors.amber[300]),
child: Column(
children: [
Container(
alignment: Alignment.topRight,
child: IconButton(
onPressed: () {
setState(() {
isDarkMode = !isDarkMode;
});
},
icon: Icon(isDarkMode ? Icons.light_mode : Icons.dark_mode))),
Padding(
padding: const EdgeInsets.all(15.0),
child: AnimatedTextKit(
key: ValueKey<bool>(isDarkMode),
animatedTexts: [
TypewriterAnimatedText(
isDarkMode ? 'Have a nice evening ;)' : 'Have a nice day :)',
cursor: isDarkMode ?'>':'<',
textStyle: TextStyle(
fontSize: 38,
color: isDarkMode ? Colors.amber[300] : Colors.grey[850]),
speed: const Duration(milliseconds: 100),
),
],
),
),
],
),
);
}
}
Result:
Background Information
I faced the same problem, when I tried to implement a dark / light change. The background color was defined in an other widget and changed, the font color was defined in the TypewriterAnimatedText Widget and only changed in the second loop. The color was not changing in the runnig animation.
Solution: use Keys
The Animation does not change beacause Flutter tries to keep the state of an StatefulWidget and the AnimatedTextKit is a Stateful Widget.
To force a rebuild you can use a Key.
a nice article can be found here: How to force a Widget to redraw in Flutter?
You can use WidgetsBinding.instance.addPostFrameCallback
For detail, you can reference https://www.didierboelens.com/faq/week2/
code snippet
#override
void initState(){
super.initState();
WidgetsBinding.instance.addPostFrameCallback((_){
updateUI(widget.curLocdata);
});
}
Related
I have a form consisting of nextformfield and elevatedButton. I want to repeat the same form just below on the screen in the same page. I have never tried to do this and it didn't work out, please help.
Here is my code in which I want to do this:
import 'dart:math';
import 'package:flutter/material.dart';
class gradysu extends StatefulWidget {
const gradysu({super.key});
#override
State<gradysu> createState() => _gradysuState();
}
class _gradysuState extends State<gradysu> {
var _formKey = GlobalKey<FormState>();
var x, y, c, d;
#override
Widget build(BuildContext context) {
return Form(
key: _formKey,
child: Scaffold(
appBar: AppBar(
centerTitle: true,
title: const Text('Квадрат'),
backgroundColor: Color.fromARGB(255, 252, 252, 252),
automaticallyImplyLeading: true,
),
body: SingleChildScrollView(
child: Container(
height: 800,
width: 639,
/* decoration: BoxDecoration(
image: DecorationImage(
image: AssetImage("assets/image/fon2.png"),
fit: BoxFit.cover,
),
),*/
child: Column(
children: [
Container(
color: Colors.brown,
height: 50.0,
width: 1000.0,
child: Center(
child: const Text(
textAlign: TextAlign.center,
style: TextStyle(fontSize: 16, color: Colors.white),
'Расчёт площади квадрата S=:'))),
Row(children: <Widget>[
Container(
padding: const EdgeInsets.all(10.0),
child: const Text('Введите градусы:',
style: TextStyle(color: Color.fromARGB(255, 0, 0, 0))),
),
Expanded(
child: Container(
padding: const EdgeInsets.all(10.0),
child: TextFormField(
keyboardType: TextInputType.number,
validator: (value) {
if (value!.isEmpty) return 'Задайте градусы';
try {
x = double.parse(value);
} catch (h) {
x;
return h.toString();
}
}))),
]),
const SizedBox(height: 20.0),
Text(
y == null ? '' : ' $y (рад) ',
style: const TextStyle(
fontSize: 20.0, color: Color.fromARGB(255, 0, 0, 0)),
),
const SizedBox(height: 20.0),
ElevatedButton(
onPressed: () {
if (_formKey.currentState!.validate()) {
setState(() {
if (x is double) y = ((x * pi) / 180);
});
}
},
style: ElevatedButton.styleFrom(
foregroundColor: Color.fromARGB(255, 235, 235,
235), //change background color of button
backgroundColor:
Colors.brown, //change text color of button
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(25),
),
elevation: 5.0,
),
child: const Padding(
padding: EdgeInsets.all(8),
child: Text(
'Вычислить',
style: TextStyle(fontSize: 20),
))),
SizedBox(height: 10.0),
],
),
),
),
),
);
}
}
class gradysu1 extends StatefulWidget {
const gradysu1({super.key});
#override
State<gradysu1> createState() => _gradysu1State();
}
class _gradysu1State extends State<gradysu1> {
var _formKey1 = GlobalKey<FormState>();
var a, c;
#override
Widget build(BuildContext context) {
return Form(
key: _formKey1,
child: Scaffold(
body: SafeArea(
child: Column(children: [
Row(children: <Widget>[
Container(
padding: const EdgeInsets.all(10.0),
child: const Text('Введите градусы:',
style: TextStyle(color: Color.fromARGB(255, 0, 0, 0))),
),
Expanded(
child: Container(
padding: const EdgeInsets.all(10.0),
child: TextFormField(
keyboardType: TextInputType.number,
validator: (value) {
if (value!.isEmpty) return 'Задайте градусы';
try {
a = double.parse(value);
} catch (h) {
a;
return h.toString();
}
}))),
]),
const SizedBox(height: 20.0),
Text(
a == null ? '' : ' $a (рад) ',
style: const TextStyle(
fontSize: 20.0, color: Color.fromARGB(255, 0, 0, 0)),
),
const SizedBox(height: 20.0),
ElevatedButton(
onPressed: () {
if (_formKey1.currentState!.validate()) {
setState(() {
if (c is double) a = ((c * pi) / 180);
});
}
},
style: ElevatedButton.styleFrom(
foregroundColor: Color.fromARGB(
255, 235, 235, 235), //change background color of button
backgroundColor: Colors.brown, //change text color of button
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(25),
),
elevation: 5.0,
),
child: const Padding(
padding: EdgeInsets.all(8),
child: Text(
'Вычислить',
style: TextStyle(fontSize: 20),
))),
]))));
}
}
This is what it looks like
And this is how it should look like
I tried to create another class, but flutter just doesn't see it, I tried to add it to the main code, but then he just didn't count, but threw an exception.
Try to create reusable widget or builder method to minimize the snippet/code-dublication.
import 'dart:math';
import 'package:flutter/material.dart';
void main(List<String> args) {
runApp(MaterialApp(
home: gradysu(),
));
}
class gradysu extends StatefulWidget {
const gradysu({super.key});
#override
State<gradysu> createState() => _gradysuState();
}
class _gradysuState extends State<gradysu> {
var _formKey = GlobalKey<FormState>();
var x, y, c, d;
#override
Widget build(BuildContext context) {
return Form(
key: _formKey,
child: Scaffold(
appBar: AppBar(
centerTitle: true,
title: const Text('Квадрат'),
backgroundColor: Color.fromARGB(255, 252, 252, 252),
automaticallyImplyLeading: true,
),
body: SingleChildScrollView(
child: Container(
height: 800,
width: 639,
/* decoration: BoxDecoration(
image: DecorationImage(
image: AssetImage("assets/image/fon2.png"),
fit: BoxFit.cover,
),
),*/
child: Column(
children: [
Container(
color: Colors.brown,
child: Center(
child: const Text(
textAlign: TextAlign.center,
style: TextStyle(fontSize: 16, color: Colors.white),
'Расчёт площади квадрата S=:'))),
Row(children: <Widget>[
Container(
padding: const EdgeInsets.all(10.0),
child: const Text('Введите градусы:',
style: TextStyle(color: Color.fromARGB(255, 0, 0, 0))),
),
Expanded(
child: Container(
padding: const EdgeInsets.all(10.0),
child: TextFormField(
keyboardType: TextInputType.number,
validator: (value) {
if (value!.isEmpty) return 'Задайте градусы';
try {
x = double.parse(value);
} catch (h) {
x;
return h.toString();
}
},
),
),
),
]),
const SizedBox(height: 20.0),
Text(
y == null ? '' : ' $y (рад) ',
style: const TextStyle(
fontSize: 20.0, color: Color.fromARGB(255, 0, 0, 0)),
),
const SizedBox(height: 20.0),
ElevatedButton(
onPressed: () {
if (_formKey.currentState!.validate()) {
setState(() {
if (x is double) y = ((x * pi) / 180);
});
}
},
style: ElevatedButton.styleFrom(
foregroundColor: Color.fromARGB(
255, 235, 235, 235), //change background color of button
backgroundColor: Colors.brown, //change text color of button
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(25),
),
elevation: 5.0,
),
child: const Padding(
padding: EdgeInsets.all(8),
child: Text(
'Вычислить',
style: TextStyle(fontSize: 20),
),
),
),
SizedBox(height: 10.0),
/// second item , you can create a build method for this
Row(children: <Widget>[
Container(
padding: const EdgeInsets.all(10.0),
child: const Text('Введите градусы:',
style: TextStyle(color: Color.fromARGB(255, 0, 0, 0))),
),
Expanded(
child: Container(
padding: const EdgeInsets.all(10.0),
child: TextFormField(
keyboardType: TextInputType.number,
validator: (value) {
if (value!.isEmpty) return 'Задайте градусы';
try {
x = double.parse(value);
} catch (h) {
x;
return h.toString();
}
},
),
),
),
]),
const SizedBox(height: 20.0),
Text(
y == null ? '' : ' $y (рад) ',
style: const TextStyle(
fontSize: 20.0, color: Color.fromARGB(255, 0, 0, 0)),
),
const SizedBox(height: 20.0),
ElevatedButton(
onPressed: () {
if (_formKey.currentState!.validate()) {
setState(() {
if (x is double) y = ((x * pi) / 180);
});
}
},
style: ElevatedButton.styleFrom(
foregroundColor: Color.fromARGB(
255, 235, 235, 235), //change background color of button
backgroundColor: Colors.brown, //change text color of button
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(25),
),
elevation: 5.0,
),
child: const Padding(
padding: EdgeInsets.all(8),
child: Text(
'Вычислить',
style: TextStyle(fontSize: 20),
),
),
),
SizedBox(height: 10.0),
],
),
),
),
),
);
}
}
I'm making an on-boarding screen. Everything is working as expected but there is some space above the image as can be seen in the provided image which shouldn't be there. I tried using MediaQuery.removePadding but that didn't help.
Please look at the code and if you can suggest anything please do. I had the same problem in another project in which I'm using Scaffold->Column->Expanded...., I'm hoping the solution for both would be similar.
class OnBoardingScreen extends StatefulWidget {
const OnBoardingScreen({Key? key}) : super(key: key);
static const String id = 'onboard-screen';
#override
State<OnBoardingScreen> createState() => _OnBoardingScreenState();
}
class _OnBoardingScreenState extends State<OnBoardingScreen> {
int _pages = 0;
final _controller = PageController();
final store = GetStorage();
onButtonPressed(context) {
store.write('onBoarding', true);
return Navigator.pushReplacementNamed(context, MainScreen.id);
}
#override
Widget build(BuildContext context) {
return Scaffold(
body: SafeArea(
child: Stack(
children: [
PageView(
padEnds: false,
controller: _controller,
onPageChanged: ((val) {
setState(() {
_pages = val.toInt();
});
}),
children: [
OnBoardPage(
boardColumn: Column(
mainAxisSize: MainAxisSize.max,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
SizedBox(
child: Image.asset(
'assets/images/1.png',
fit: BoxFit.fill,
),
),
const Padding(
padding: EdgeInsets.only(left: 16.0, bottom: 10),
child: Text(
'Welcome\nto Fiesto',
textAlign: TextAlign.left,
style: TextStyle(
fontWeight: FontWeight.bold,
fontSize: 44,
color: Colors.white),
),
),
const Padding(
padding: EdgeInsets.only(left: 16.0),
child: Text(
'Book restaurants, cafes,\nbanquet halls, marriage halls, etc',
textAlign: TextAlign.left,
style: TextStyle(
fontWeight: FontWeight.normal,
fontSize: 22,
color: Colors.white),
),
),
],
),
),
OnBoardPage(
boardColumn: Column(
mainAxisSize: MainAxisSize.max,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
SizedBox(
child: Image.asset(
'assets/images/2.png',
),
),
const Padding(
padding: EdgeInsets.only(left: 16.0, bottom: 10),
child: Text(
'Fiesto\nParty Services',
textAlign: TextAlign.left,
style: TextStyle(
fontWeight: FontWeight.bold,
fontSize: 44,
color: Colors.white),
),
),
const Padding(
padding: EdgeInsets.only(left: 16.0),
child: Text(
'Get all kinds of party services and\nsolutions',
textAlign: TextAlign.left,
style: TextStyle(
fontWeight: FontWeight.normal,
fontSize: 22,
color: Colors.white),
),
),
],
),
),
Positioned.fill(
bottom: 180,
child: Align(
alignment: Alignment.bottomCenter,
child: Row(
mainAxisSize: MainAxisSize.min,
mainAxisAlignment: MainAxisAlignment.center,
children: [
AnimatedSmoothIndicator(
//https://pub.dev/smooth_page_indicator
activeIndex: _pages,
count: 5,
effect: const JumpingDotEffect(
dotHeight: 16,
dotWidth: 16,
jumpScale: .7,
verticalOffset: 15,
dotColor: Colors.grey,
activeDotColor: Colors.yellow,
),
),
],
),
),
),
Positioned(
right: 16,
bottom: 120,
child: TextButton(
child: const Text(
'Skip & Proceed to\nLogin/Signup',
textAlign: TextAlign.end,
style: TextStyle(
color: Color.fromARGB(255, 117, 13, 13),
fontSize: 14,
decoration: TextDecoration.underline,
),
),
onPressed: () {
onButtonPressed(context);
},
),
),
Positioned(
right: 16,
bottom: 50,
width: 150,
height: 50,
child: ElevatedButton(
onPressed: () {
if (_pages == 0) {
_controller.animateToPage(
1,
duration: const Duration(milliseconds: 400),
curve: Curves.easeInOut,
);
} else if (_pages == 1) {
_controller.animateToPage(
2,
duration: const Duration(milliseconds: 400),
curve: Curves.easeInOut,
);
} else if (_pages == 2) {
_controller.animateToPage(
3,
duration: const Duration(milliseconds: 400),
curve: Curves.easeInOut,
);
} else if (_pages == 3) {
_controller.animateToPage(
4,
duration: const Duration(milliseconds: 400),
curve: Curves.easeInOut,
);
} else if (_pages == 4) {
onButtonPressed(context);
}
},
child: _pages <= 3
? const Text(
'Next',
style: TextStyle(fontSize: 22),
)
: const Text(
'Login/Signup',
style: TextStyle(fontSize: 22),
),
),
),
],
),
),
);
}
}
class OnBoardPage extends StatelessWidget {
final Column? boardColumn;
const OnBoardPage({Key? key, this.boardColumn}) : super(key: key);
#override
Widget build(BuildContext context) {
return Container(
color: Color.fromARGB(255, 0, 0, 0),
child: boardColumn,
);
}
}
You have this problem because the Column widgets have a default mainAxisAlignment: MainAxisAlignment.center so I am changing it to: mainAxisAlignment: MainAxisAlignment.startAlso my tests on your code indicate the nature of the image is playing a role. Because its works like you want on my images.
Remove SafeArea or assign top: false.
i m creating an application in which i have to change the state of a button save the state. and afterwards when that page is open again then the changed state should be displayed.
for example: if i click on the favorite button then its state gets changed from unselected to selected so after this when i closed the app and open it again then the favorite button should be in selected state rather than in unselected state.
please help me out with this issue.
i have used a variable is which the value is stored and then i m checking the condition .
import 'package:EventsApp/Models/EventModel.dart';
import 'package:flutter/material.dart';
import 'package:fluttertoast/fluttertoast.dart';
import 'package:http/http.dart' as http;
import 'package:favorite_button/favorite_button.dart';
import 'package:shared_preferences/shared_preferences.dart';
class DetailPage extends StatefulWidget {
final String image;
final EventModel value;
const DetailPage({Key key, this.image, #required this.value})
: super(key: key);
#override
_DetailPageState createState() => _DetailPageState();
}
class _DetailPageState extends State<DetailPage> {
String eventId;
String userId;
bool isPartcipated = false;
bool isfavorite;
Future<http.Response> participateinEvent() async {
SharedPreferences prefs = await SharedPreferences.getInstance();
var uid = prefs.getString('userId');
var eveid = prefs.getString('eventId');
var res = await http.post(
'http://10.0.2.2:8080/eventusermapping/addParticipant/' +
uid +
'/' +
eveid);
print(res.body);
Fluttertoast.showToast(
msg: 'Participation Successful',
toastLength: Toast.LENGTH_SHORT,
gravity: ToastGravity.BOTTOM,
timeInSecForIos: 1,
);
}
Future<http.Response> addfavorite() async {
SharedPreferences prefs = await SharedPreferences.getInstance();
var uid = prefs.getString('userId');
var eveid = prefs.getString('eventId');
var res = await http
.post('http://10.0.2.2:8080/event/addtoFavorites/' + uid + '/' + eveid);
Fluttertoast.showToast(
msg: 'Added to favorite',
toastLength: Toast.LENGTH_SHORT,
gravity: ToastGravity.BOTTOM,
timeInSecForIos: 1,
);
setState(() {
isfavorite = true;
});
}
Future<http.Response> removefavorite() async {
SharedPreferences prefs = await SharedPreferences.getInstance();
var uid = prefs.getString('userId');
var eveid = prefs.getString('eventId');
var res = await http.post(
'http://10.0.2.2:8080/event/removeFromFavorites/' + uid + '/' + eveid);
Fluttertoast.showToast(
msg: 'Removed from favorite',
toastLength: Toast.LENGTH_SHORT,
gravity: ToastGravity.BOTTOM,
timeInSecForIos: 1,
);
setState(() {
isfavorite = false;
});
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: new AppBar(
leading: IconButton(
icon: Icon(Icons.arrow_back, color: Color(0xffffffff)),
onPressed: () => Navigator.of(context).pop(),
),
centerTitle: true,
backgroundColor: Colors.lightBlue[900],
elevation: 0.0,
title: new Text("Event Details",
style: const TextStyle(
color: const Color(0xffffffff),
fontWeight: FontWeight.w500,
fontStyle: FontStyle.normal,
fontSize: 19.0)),
),
body: Container(
child: SingleChildScrollView(
child: Column(
children: [
Container(
width: double.infinity,
height: 400.0,
child: Stack(
children: [
Positioned(
top: 0,
left: 0,
right: 0,
bottom: 90,
child: Container(
decoration: BoxDecoration(
image: DecorationImage(
image: NetworkImage('${widget.value.coverimg}'),
fit: BoxFit.fitWidth,
),
),
// child: Column(
// children: [
// IconButton(
// icon: Icon(Icons.arrow_back),
// onPressed: () => Navigator.pop(context),
// iconSize: 30.0,
// color: Colors.lightBlue[900],
// ),
// ],
// ),
),
),
Positioned(
top: 270,
left: 20,
right: 20,
bottom: 0,
child: Card(
elevation: 0.5,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(25.0),
),
child: Padding(
padding: EdgeInsets.all(15.0),
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Row(
mainAxisAlignment:
MainAxisAlignment.spaceBetween,
children: [
Text(
'${widget.value.name}',
style: TextStyle(
fontSize: 23.0,
fontWeight: FontWeight.bold,
color: Colors.lightBlue[900]),
),
],
),
Row(
children: [
Icon(
Icons.location_on,
color: Colors.grey,
size: 20,
),
SizedBox(width: 12.0),
Text(
" Kalyan west",
style: TextStyle(
fontSize: 18,
color: Colors.lightBlue[900]),
),
],
),
Row(
children: [
Icon(
Icons.calendar_today,
color: Colors.grey,
size: 20,
),
SizedBox(width: 12.0),
Text(
'${widget.value.date}',
style: TextStyle(
fontSize: 17,
color: Colors.lightBlue[900]),
),
],
),
],
),
),
),
),
],
),
),
Container(
width: double.infinity,
child: Column(
children: [
SizedBox(height: 12.0),
ListTile(
leading: CircleAvatar(
radius: 25,
backgroundImage:
NetworkImage('${widget.value.eventheadphoto}'),
),
title: Text(
'${widget.value.eventheadname}',
style: TextStyle(
fontWeight: FontWeight.bold,
fontSize: 20,
color: Colors.lightBlue[900]),
),
subtitle: Text(
"Event Head",
style: TextStyle(fontSize: 17, color: Colors.grey),
),
),
SizedBox(height: 15.0),
Padding(
padding: EdgeInsets.symmetric(horizontal: 18),
child: Text(
'${widget.value.description}',
textAlign: TextAlign.left,
style: TextStyle(
fontSize: 19, color: Colors.lightBlue[900]),
),
),
SizedBox(height: 20.0),
Container(
child: Row(
children: [
Padding(
padding: const EdgeInsets.only(left: 70.0),
child: Center(
child: SizedBox(
width: 190,
child: isPartcipated
? RaisedButton(
onPressed: null,
shape: RoundedRectangleBorder(
borderRadius:
BorderRadius.circular(30.0)),
color: Colors.grey,
child: Text(
"Participated",
style: TextStyle(
color: Colors.white,
fontSize: 18.0,
letterSpacing: 1.5),
),
disabledColor: Colors.black12,
disabledElevation: 1,
disabledTextColor: Colors.black,
)
: RaisedButton(
onPressed: () {
participateinEvent();
setState(() {
isPartcipated = !isPartcipated;
});
},
shape: RoundedRectangleBorder(
borderRadius:
BorderRadius.circular(30.0)),
color: Colors.lightBlue[900],
child: Text(
"Participate",
style: TextStyle(
color: Colors.white,
fontSize: 18.0,
letterSpacing: 1.5),
),
),
),
),
),
Padding(
padding: EdgeInsets.only(left: 50.0),
child: Container(
decoration: BoxDecoration(
// borderRadius: BorderRadius.circular(50),
// color: Colors.blue,
// border:
// Border.all(width: 1, color: Colors.grey),
),
child: FavoriteButton(
isFavorite: false,
valueChanged: (isfavorite) {
if (isfavorite) {
addfavorite();
} else {
removefavorite();
}
},
), //IconButton(
// iconSize: 35,
// color: Colors.redAccent[400],
// icon: Icon(Icons.favorite_border),
// tooltip: 'Add to Favorite',
// onPressed: () {}),
),
)
],
),
),
SizedBox(height: 30.0)
],
),
)
],
),
),
),
);
}
}
You not storing the button state in addFavourite method.
SharedPreferences prefs = await SharedPreferences.getInstance();
prefs.setBool('stateOfButton', true);
When you open your app again, you can get the button state like how you get for the userId and eventId.
prefs.getBool('stateOfButton');
I don't know if it's possible to just rewrite the initial value of the variables for the following executions of the app. What is possible to do is to store this values somehow, and load them before loading the screen with the favorite button.
What i would do is to use path provider(https://pub.dev/packages/path_provider) and store something like(lets suppose we are talking about movies)
"user":{
"favorited movies" : [
12
23
]
}
and then before loading the button, checking the movie id is in the user favorited movies array. You can find a good example of how exactly would you store in the complete example in https://flutter.dev/docs/cookbook/persistence/reading-writing-files
If you think about the standard way to deal with State management in your app I suggest you look into BLoC. It requires an initial learning curve with it but it is worth it.
Feel free to find more info in the 'Counter' example on the website
https://bloclibrary.dev/#/gettingstarted
Here is another good talk by Felix, who maintains bloc library
https://www.youtube.com/watch?v=knMvKPKBzGE&t=2327s
you can use this package flutter shared preferences
you should make get and set methods
class StorageService {
Future<String> getTokenAsync() async {
SharedPreferences instances = await getInstanceAsync();
String stringValue = instances.getString(Constant.userToken);
return stringValue; }
Future<void> setTokenAsync(String token) async {
SharedPreferences instances = await getInstanceAsync();
instances.setString(Constant.userToken, token); } }
String token = await _storageService.getTokenAsync();
_storageService.setTokenAsync(entity.token);
I have a problem with RadioListTile it doesn't work
Im trying to create a list of RadioListTile to fill in with my data from firebase using for loop. When I click it it do receive the action, but I cannot check the box when click on it.
I have been trying to solve it for days. Anyone can help?
This is my code:
import 'package:eatwell/src/helpers/changescreen.dart';
import 'package:eatwell/src/model/itemmodel.dart';
import 'package:eatwell/src/model/platemodel.dart';
import 'package:eatwell/src/pages/cartPage.dart';
import 'package:eatwell/src/provider/customplate.dart';
import 'package:eatwell/src/provider/item.dart';
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
class CustomDetail extends StatefulWidget {
final CustomModel custom;
const CustomDetail({Key key, this.custom}) : super(key: key);
#override
_CustomDetail createState() => _CustomDetail();
}
class _CustomDetail extends State<CustomDetail> {
#override
Widget build(BuildContext context) {
final carbsProvider = Provider.of<CarbsProvider>(context);
var mycarb = 1;
return Scaffold(
appBar: AppBar(
title: Text(
"Preset Meal",
style: TextStyle(
fontSize: 30.0,
fontWeight: FontWeight.bold,
color: Colors.black,
fontFamily: 'DancingScript',
),
),
centerTitle: true,
actions: <Widget>[
Padding(
padding: const EdgeInsets.only(bottom: 8.0, right: 8.0),
child: Stack(
children: <Widget>[
IconButton(
icon: Icon(
Icons.shopping_bag_outlined,
size: 40,
),
onPressed: () {
changeScreen(context, Cart());
}),
Positioned(
right: 3,
bottom: 0,
child: Container(
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(10),
boxShadow: [
BoxShadow(
color: Colors.grey,
offset: Offset(2, 3),
blurRadius: 3)
]),
child: Padding(
padding: const EdgeInsets.only(left: 4, right: 4),
child: Text(
"2",
style: TextStyle(
color: Colors.red,
fontSize: 16.0,
fontWeight: FontWeight.bold),
),
),
),
)
],
),
)
],
),
body: SafeArea(
child: ListView(
children: <Widget>[
Padding(
padding: const EdgeInsets.only(
left: 20.0, right: 20, bottom: 10, top: 30),
child: Container(
decoration: BoxDecoration(
color: Colors.cyanAccent,
borderRadius: BorderRadius.circular(100),
),
height: 300,
alignment: Alignment.center,
child: Image(
image: NetworkImage(widget.custom.image),
height: 300,
width: 300,
),
),
),
Text(
widget.custom.name,
style: TextStyle(fontSize: 30.0, fontWeight: FontWeight.bold),
textAlign: TextAlign.center,
),
Text(
("RM ${widget.custom.price}"),
style: TextStyle(fontSize: 30.0, fontWeight: FontWeight.bold),
textAlign: TextAlign.center,
),
for (var i = 0; i < widget.custom.carbnum; i++)
Column(
children: <Widget>[
ListTile(
title: Text("Choose Your Carbohydrates"),
),
for (var i = 0; i < carbsProvider.carbs.length; i++)
RadioListTile(
title: Text(carbsProvider.carbs[i].name),
value: i,
onChanged: (var v) {
print("object");
mycarb = v;
},
groupValue: mycarb,
)
],
),
// for (var i = 0; i < widget.custom.fooditems.length; i++)
// Text(
// widget.custom.fooditems[i],
// style: TextStyle(fontSize: 30.0, fontWeight: FontWeight.bold),
// )
],
),
));
}
}
Wrap your onChanged in setState.
just like
onChanged: (var v) {
setState((){
print("object");
mycarb = v;
});
},
According to the docs:
Calling setState notifies the framework that the internal state of this object has changed in a way that might impact the user interface in this subtree, which causes the framework to schedule a build for this State object.
Use setState method in onChanged method of RadioListTile widget and as answered by Abdul Qadir.
In flutter, I want to make an application that scans qr code and display the qr text.
I have two buttons, which are done, scan again.
And how to put that 2 button, bottom of that scan area. If i try to put that button inside expanded layer, it looks all red
Here is the code & screenshot.
How can i solve this ?
import 'package:flutter/material.dart';
import 'package:qr_code_scanner/qr_code_scanner.dart';
import 'package:qr_code_scanner/qr_scanner_overlay_shape.dart';
void main() => runApp(MaterialApp(home: QRSCAN()));
const flash_on = "FLASH ON";
const flash_off = "FLASH OFF";
const front_camera = "FRONT CAMERA";
const back_camera = "BACK CAMERA";
class QRSCAN extends StatefulWidget {
const QRSCAN({
Key key,
}) : super(key: key);
#override
State<StatefulWidget> createState() => _QRSCANState();
}
class _QRSCANState extends State<QRSCAN> {
bool Done_Button = false;
var qrText = "";
QRViewController controller;
final GlobalKey qrKey = GlobalKey(debugLabel: 'QR');
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
leading: IconButton(
icon: Icon(Icons.arrow_back, color: Colors.blueAccent),
onPressed: () {
Navigator.pop(context);
controller?.pauseCamera();
},
),
elevation: 0.0,
backgroundColor: Colors.white,
actions: <Widget>[
IconButton(
icon: Icon(Icons.help_outline, color: Colors.grey,),
onPressed: () {},
),
],
),
body: Column(
children: <Widget>[
Expanded(
child: QRView(
key: qrKey,
onQRViewCreated: _onQRViewCreated,
overlay: QrScannerOverlayShape(
borderColor: Colors.blueAccent,
borderRadius: 10,
borderLength: 130,
borderWidth: 5,
overlayColor: Color(0xff010040),
),
),
flex: 4,
),
Expanded(
child: FittedBox(
fit: BoxFit.contain,
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: <Widget>[
Text("$qrText", style: TextStyle(color: Colors.black,),),
InkWell(
onTap: () async {
Navigator.pop(context);
},
child: Container(
width: 100.0,
height: 50.0,
decoration: BoxDecoration(
borderRadius: BorderRadius.all(Radius.circular(5)),
gradient: LinearGradient(colors: [
Color(0xFF1E75BB),
Color(0xFF1EEABB),
])),
child: Center(
child: Text(
'Done',
style: TextStyle(
color: Colors.white,
letterSpacing: 1.5,
fontSize: 12.0,
fontWeight: FontWeight.bold,
fontFamily: 'Play',
),
),
),
),
),
SizedBox(
height: 25,
),
InkWell(
onTap: () async {
setState(() {
qrText = "";
controller?.resumeCamera();
Done_Button = false;
});
},
child: Container(
width: 100.0,
height: 50.0,
decoration: BoxDecoration(
borderRadius: BorderRadius.all(Radius.circular(5)),
gradient: LinearGradient(colors: [
Color(0xFF1E75BB),
Color(0xFF1EEABB),
])),
child: Center(
child: Text(
'Again',
style: TextStyle(
color: Colors.white,
letterSpacing: 1.5,
fontSize: 12.0,
fontWeight: FontWeight.bold,
fontFamily: 'Play',
),
),
),
),
),
],
),
),
flex: 1,
),
],
),
);
}
_isFlashOn(String current) {
return flash_on == current;
}
_isBackCamera(String current) {
return back_camera == current;
}
void _onQRViewCreated(QRViewController controller) {
this.controller = controller;
controller.scannedDataStream.listen((scanData) {
setState(() {
qrText = scanData;
controller?.pauseCamera();
Done_Button = true;
});
});
}
#override
void dispose() {
controller.dispose();
super.dispose();
}
}
you can refactor your code as follows
` Column(children: <Widget>[
/* QRView(
key: qrKey,
onQRViewCreated: _onQRViewCreated,
overlay: QrScannerOverlayShape(
borderColor: Colors.blueAccent,
borderRadius: 10,
borderLength: 130,
borderWidth: 5,
overlayColor: Color(0xff010040),
),
),*/
SizedBox(height:5),
Center(
child: Container(height: 100, color: Colors.white, width: 100),
),
Text(
"$qrText",
style: TextStyle(
color: Colors.black,
),
),
InkWell(
onTap: () async {
Navigator.pop(context);
},
child: Container(
width: 100.0,
height: 50.0,
decoration: BoxDecoration(
borderRadius: BorderRadius.all(Radius.circular(5)),
gradient: LinearGradient(colors: [
Color(0xFF1E75BB),
Color(0xFF1EEABB),
])),
child: Center(
child: Text(
'Done',
style: TextStyle(
color: Colors.white,
letterSpacing: 1.5,
fontSize: 12.0,
fontWeight: FontWeight.bold,
fontFamily: 'Play',
),
),
),
),
),
SizedBox(
height: 25,
),
InkWell(
onTap: () async {
setState(() {
qrText = "";
// controller?.resumeCamera();
// Done_Button = false;
});
},
child: Container(
width: 100.0,
height: 50.0,
decoration: BoxDecoration(
borderRadius: BorderRadius.all(Radius.circular(5)),
gradient: LinearGradient(colors: [
Color(0xFF1E75BB),
Color(0xFF1EEABB),
])),
child: Center(
child: Text(
'Again',
style: TextStyle(
color: Colors.white,
letterSpacing: 1.5,
fontSize: 12.0,
fontWeight: FontWeight.bold,
fontFamily: 'Play',
),
),
),
),
),
]),
);`