I am building a Weather app for learning and at the beginning of app I want to get users location. Splash screen is stateless widget and don't do anything. When the locations is available I want to push to the another screen.
I am able to do it but is this a correct way to do(Please review below code)?.
Let me know any other solutions.
I call the getLocation method before returning the widget from build method. Is this the ideal way of doing? Because this screen state won't be updating.
class LaunchScreen extends StatelessWidget {
static const String id = 'launch_screen';
void getLocation(BuildContext context) async {
LocationData location = await LocationService().getCurrentLocation();
if (location != null) {
// Go to home
print(location.latitude);
print(location.longitude);
} else {
// Error fetching location
}
}
#override
Widget build(BuildContext context) {
getLocation(context);
return Scaffold(
body: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Expanded(
child: Container(),
),
Center(
child: Image(
image: AssetImage('images/launch_screen/app_logo.png'),
),
),
SizedBox(
height: 8,
),
Center(
child: Shimmer.fromColors(
baseColor: Colors.white.withOpacity(0.6),
highlightColor: Colors.white,
child: Text(
'Forecasts',
style: GoogleFonts.montserratAlternates(
textStyle:
TextStyle(fontSize: 60, fontWeight: FontWeight.w300),
color: Colors.white.withOpacity(0.6)),
),
),
),
Expanded(
child: Container(),
),
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text(
'Made with ❤️ ',
style: TextStyle(
fontSize: 12,
fontWeight: FontWeight.w300,
color: Colors.white.withOpacity(0.5)),
),
Text(
'Parth Adroja',
style: TextStyle(
fontSize: 12,
fontWeight: FontWeight.w500,
color: Colors.white.withOpacity(0.5)),
),
],
),
SizedBox(
height: 20,
)
],
),
);
}
}
You can use the FutureBuilder to do it.
like:
Widget build(BuildContext context) {
return FutureBuilder(
initialData: null,
future: getLocation(),
builder: (context, snap){
if(snap.hasData){
return FullDataWidget(snap.data);
}else{
return SplashScreen();
}
},
);
}
Related
I want to create a reusable WidgetMonthPicker with my own design..
Like other widget switch, user gets value true or false, here I want to get value of selected month and year from this custom widget..
user don't need to code for taponPlus and tapOnMinus buttons...
design is shown in image
here is my code
class _HomeScreenState extends State<HomeScreen> {
int current_month = DateTime.now().month;
int current_year = DateTime.now().year;
#override
Widget build(BuildContext context) {
return Scaffold(
body: SafeArea(
child: Column(children: [
Container(
height: 100,
child: Material(
color: Colors.grey,
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
IconButton(
onPressed: () {
setState(() {
if (current_month == 1) {
current_year--;
current_month = 12;
} else
current_month--;
});
},
icon: Icon(Icons.arrow_back)),
Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text(
current_year.toString(),
style: TextStyle(fontWeight: FontWeight.bold),
),
SizedBox(
height: 10,
),
Text(
DateFormat('MMMM')
.format(DateTime(0, current_month))
.toString(),
style: TextStyle(
fontSize: 30,
color: Colors.black,
fontWeight: FontWeight.bold),
),
],
),
IconButton(
onPressed: () {
setState(() {
if (current_month == 12) {
current_year++;
current_month = 1;
} else
current_month++;
});
},
icon: Icon(Icons.arrow_forward)),
],
),
),
),
Expanded(
child: Container(
color: Colors.blue,
child: Center(child: Text('Output')),
),
),
]),
),
);
}
}
I am new to flutter development and i am doing it from past 3 months and i never have that issue when i press back.
Whenever i press back and back to home screen screen overlap:
here is my code of home screen:
class HomePage extends StatefulWidget {
#override
State<HomePage> createState() => _HomePageState();
}
class _HomePageState extends State<HomePage> {
BannerAd _bottomBannerAd;
bool _isBottomBannerAdLoaded = false;
final BannerAd myBanner = BannerAd(
adUnitId: 'ca-app-pub-3940256099942544/6300978111',
size: AdSize.banner,
request: AdRequest(),
listener: BannerAdListener(),
);
#override
void initState() {
super.initState();
myBanner.load();
}
#override
Widget build(BuildContext context) {
return Container(
child: Scaffold(
bottomNavigationBar: Container(
height: 50,
width: 320,
child: AdWidget(ad: myBanner,),
) ,
backgroundColor: Colors.transparent,
body: SingleChildScrollView(
child: Column(
children: <Widget>[NavBar(), Body()],
)),
));
}
}
class Body extends StatelessWidget {
#override
Widget build(BuildContext context) {
return ResponsiveLayout(
largeScreen: LargeChild(),
smallScreen: SmallChild(),
);
}
}
class LargeChild extends StatelessWidget {
#override
Widget build(BuildContext context) {
return SizedBox(
height: 600,
child: Stack(
fit: StackFit.expand,
children: <Widget>[
FractionallySizedBox(
alignment: Alignment.centerLeft,
widthFactor: .6,
child: Padding(
padding: EdgeInsets.only(left: 48),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text(
"Memory Game",
style: TextStyle(
fontSize: 60,
fontWeight: FontWeight.bold,
fontFamily: "Montserrat-Regular",
color: Color(0xFF111111)),
),
RichText(
text: TextSpan(
text: "Say Hi to ",
style: TextStyle(
fontSize: 60, color: Color(0xFF8591B0)),
children: [
TextSpan(
text: "🐱",
style: TextStyle(
fontSize: 60,
fontWeight: FontWeight.bold,
// color: Colors.black54
))
],
),
),
SizedBox(
height: 40,
),
Search()
])))
],
),
);
}
}
class SmallChild extends StatelessWidget {
#override
Widget build(BuildContext context) {
return SingleChildScrollView(
child: Padding(
padding: EdgeInsets.all(40),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Text(
"Memory Game!",
style: TextStyle(
fontSize: 60,
fontWeight: FontWeight.bold,
fontFamily: "Montserrat-Regular",
color: Colors.white),
),
RichText(
text: TextSpan(
text: "Play Now",
style: TextStyle(fontSize: 60, color: Color(0xFF8591B0)),
children: [
TextSpan(
text: "🐱",
style: TextStyle(
fontSize: 40,
fontWeight: FontWeight.bold,
))
],
),
),
SizedBox(
height: 32,
),
Search(),
SizedBox(
height: 30,
)
],
),
));
}
}
Problem:Whenever i press back whole screen apears in back of home screen as you can see in the provided gif.
Can someone please tell me that why is this happening?
Its happening just because you have written backgroundColor: Colors.transparent, in your Scaffold
Try to change it with some another color and check it out, you will not face the problem.
I'm getting this error as I wrote on the title above. I'm a new learner in flutter, I have seeking for some solution to solve it, example this link below.
But I still cannot solve the problem can anyone help me on that?
I know this might be a duplicate question, I have try my best to understand it and still cannot solve, can anyone help out? Thanks. And
below is the main.dart code :
import 'package:flutter/material.dart';
import 'package:sharing_app/MyFlutterApp_icons.dart';
import 'package:sharing_app/Sharer.dart';
import 'package:sharing_app/Customer.dart';
void main() => runApp(MainPage());
class MainPage extends StatefulWidget{
Home createState()=> Home();
}
class Home extends State<MainPage> {
#override
Widget build(BuildContext context) {
Scaffold(
appBar: AppBar(
backgroundColor: Colors.amber,
centerTitle: true,
title: Text('Welcome',
style: TextStyle(
fontSize: 16.0,
color: Colors.black87,
letterSpacing: 1.0,
),
),
),
body: Column(
children: [
Row(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
Expanded(
flex: 1,
child: Container(
padding: EdgeInsets.all(20.0),
child: RaisedButton.icon(
onPressed: () {
Navigator.of(context)
.push(MaterialPageRoute(
builder: (context) {
return Sharer();
}
)
);
},
icon: Icon(
Icons.account_circle,
),
label: Text(
'Login as Sharer',
style: TextStyle(
fontFamily: 'MyFlutterApp',
color: Colors.black87,
letterSpacing: 1.0,
),
),
),
),
),
],
),
Row(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
Expanded(
flex: 1,
child: Container(
padding: EdgeInsets.all(20.0),
child: RaisedButton.icon(
onPressed: () {
Navigator.of(context)
.push(MaterialPageRoute(
builder: (context) {
return Customer();
}
)
);
},
icon: Icon(
Icons.account_circle,
),
label: Text(
'Login as Customer',
style: TextStyle(
fontFamily: 'MyFlutterApp',
color: Colors.black87,
letterSpacing: 1.0,
),
),
),
),
),
],
),
],
),
);
}
}
Error : it tells on the android studio console "A build function returned null.". Then, "To return an empty space that causes the building widget to fill available room, return "Container()". To return an empty space that takes as little room as possible, return "Container(width: 0.0, height: 0.0)"."
Can anyone help out?
Well you just forget the return statement before your Scafffold :
class Home extends State<MainPage> {
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
The build method expect a Widget (in you case the scaffold) to be return so it can draw / build this widget.
i want add two line of different type text in my homepage. But when i add another Text widget nothing happen. Here is my code;
class Body extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Column(
children: <Widget>[
Center(
child: Text(
"Hello",
style: TextStyle(fontSize: 28, color: Colors.white),
),
),
],
);
}
}
i want to get this output in picture exactly.
Thanks a lot!
see input
You need to use container to give blue background and then use Column and Text widget. You are using Text color as white with background color also white, how will that show...
class Body extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Container(
color: Colors.blue,
child: Column(
children: <Widget>[
Center(
child: Text(
"Hello",
style: TextStyle(fontSize: 28, color: Colors.white),
),
),
Center(
child: Text(
"Izabella",
style: TextStyle(fontSize: 38, color: Colors.white),
),
),
],
),
);
}
}
this is like your Image ...
class Body extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Column(
children: <Widget>[
Center(
child: Text(
"Hello",
style: TextStyle(fontSize: 14, color: Colors.white),
),
),
Center(
child: Text(
"Izabella",
style: TextStyle(fontSize: 38, color: Colors.white),
),
),
],
);
}
}
I hope this help you...
I hope this answers your question
class Body extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.blue,
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
// first text
Text('Hello', style: TextStyle(fontSize: 15, color: Colors.white)),
// second text
Text('Izabella',
style: TextStyle(fontSize: 25, color: Colors.white)),
],
),
),
);
}
}
I am trying to show the progessbar until the data is fetched. At init state I have the api called. It shows the error as shown in the image and then the layouts are shown without showing the progress bar. I am new to flutter and could not get through this.
I have implemented as follows:
#override
void initState() {
super.initState();
getDetails();
}
GetDetails method
void getDetails() async {
setState(() {
_isLoading = true;
});
MenuDetailsResponse moreResponse = await getMenuDetails(widget.id);
if (moreResponse != null && moreResponse.data != null) {
setState(() {
details = moreResponse.data;
if (details.detail.maxQty != null) {
maxQtyController =
new TextEditingController(text: details.detail.maxQty.toString());
} else {
maxQtyController = new TextEditingController();
}
print(details);
_isLoading = false;
});
} else if (moreResponse != null) {
setState(() {
_isLoading = false;
});
showAlerts(context, "Sorry!!", moreResponse.message, AlertType.error);
} else {
setState(() {
_isLoading = false;
});
showAlerts(context, "Sorry!!",
"Something went wrong, Please try again later!!", AlertType.error);
}
}
Build Method:
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
backgroundColor: Colors.white,
iconTheme: IconThemeData(color: Theme.of(context).primaryColor),
title: Text(
"Menu Details",
style: TextStyle(color: Theme.of(context).primaryColor),
),
),
body: Stack(
children: <Widget>[
Opacity(
opacity: _isLoading
? 0.3
: 1, // You can reduce this when loading to give different effect
child: AbsorbPointer(
absorbing: _isLoading,
child: _buildLayout(),
),
),
Opacity(
opacity: _isLoading ? 1.0 : 0,
child: Center(
child: CircularProgressIndicator(
backgroundColor: Theme.of(context).primaryColor,
),
)),
],
),
);
}
BuildLayout widget
Widget _buildLayout() {
return Container(
margin: EdgeInsets.all(10),
child: Wrap(
children: <Widget>[
Column(
children: <Widget>[
SizedBox(height: 20),
Text(
"Enter max quantity for today",
style: TextStyle(color: Theme.of(context).primaryColor),
),
SizedBox(height: 20),
_buildTopItems(),
],
)
],
),
);
}
Widget topItems
Widget _buildTopItems() {
return Container(
margin: EdgeInsets.only(top: 10),
child: Wrap(
children: <Widget>[
Row(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
Container(
child: Image.network(
details.detail.image,
height: 150,
width: 150,
fit: BoxFit.fill,
),
),
SizedBox(
width: 10,
),
Expanded(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Text(
details.detail.name,
style: TextStyle(fontSize: 18),
),
SizedBox(height: 5),
Row(
children: <Widget>[
Text("Rs " + details.detail.price.toString(),
style: TextStyle(
decoration: TextDecoration.lineThrough)),
SizedBox(width: 5),
Text("Rs " + details.detail.discountPrice.toString(),
style: TextStyle(
fontSize: 17,
color: Theme.of(context).primaryColor,
))
],
),
SizedBox(height: 5),
Text(details.detail.foodtypedata.foodType),
SizedBox(height: 5),
StarRating(
rating: double.parse(details.detail.rating),
size: 24.0,
),
SizedBox(height: 5),
details.detail.status >= 1
? Text(
"Available",
style: TextStyle(
color: Theme.of(context).primaryColor),
)
: Text(
"UnAvailable",
style: TextStyle(color: Colors.red),
),
Text(
"- " + details.detail.createdAt,
textAlign: TextAlign.left,
),
],
))
]),
],
),
);
}
It appears to me that details is a class field and when build is called for the first time it will be null.
This happens because you are filling details on initState, but getDetails is an asynchronous call, so initState will execute and queue getDetails for later, as it's a Future, so it executes in the future, not right now. Right now Flutter goes to build and details is accessed there which is still null.
If you need data from a Future inside your build method, use a FutureBuilder.
I solved this by changing buildmethod as follows:
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
backgroundColor: Colors.white,
iconTheme: IconThemeData(color: Theme.of(context).primaryColor),
title: Text(
"Menu Details",
style: TextStyle(color: Theme.of(context).primaryColor),
),
),
body: _isLoading
? Center(
child: CircularProgressIndicator(
backgroundColor: Theme.of(context).primaryColor,
),
)
: _buildLayout()
);
}