Pull down in a flutter app to refresh the app state - flutter

I want to update/refresh the balanceAvailable value inside the Text Widget by pulling down the mobile screen in a flutter app.
I have attached a sample code that I am working on for your reference.
I does not seem to work as intended. I would be grateful if someone can provide a solution to this issue.
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatefulWidget {
#override
_MyAppState createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
final GlobalKey<RefreshIndicatorState> _refreshIndicatorKey =
GlobalKey<RefreshIndicatorState>();
double balanceAvailable = 0.0;
Future<void> _onRefreshing() async {
setState(() async {
balanceAvailable = 100;
print('newbalance : $balanceAvailable');
});
}
#override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
body: RefreshIndicator(
key: _refreshIndicatorKey,
onRefresh: _onRefreshing,
child: Container(
width: double.infinity,
color: Colors.lightBlue,
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
RaisedButton(
onPressed: () async {},
child: Text("Just a Button 1"),
),
SizedBox(
height: 100,
),
Text('$balanceAvailable'),
],
),
)),
),
);
}
}

In order for RefreshIndicator to work, it needs a vertically scrollable descendant like a ListView:
RefreshIndicator(
key: _refreshIndicatorKey,
onRefresh: _onRefreshing,
child: ListView(
physics: const AlwaysScrollableScrollPhysics(),
children: [
Container(
width: double.infinity,
color: Colors.lightBlue,
child: Column(
mainAxisSize: MainAxisSize.min,
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
RaisedButton(
onPressed: () async {},
child: Text("Just a Button 1"),
),
SizedBox(
height: 100,
),
Text('$balanceAvailable'),
],
),
),
],
),
)

Related

ChoiceChip not expanding with IntrinsicWidth

I'm wondering why ChoiceChip is not expanding like ElevatedButton does.
Here is an example: (look at dartpad)
import 'package:flutter/material.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
body: MyWidget(),
),
);
}
}
class MyWidget extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Column(children: [
IntrinsicWidth(
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
mainAxisSize: MainAxisSize.min,
children: [
Expanded(
child: ElevatedButton(
child: const Text('Larger Text'),
onPressed: () {},
)),
Expanded(
child: ElevatedButton(
child: const Text('Text'),
onPressed: () {},
)),
],
)),
IntrinsicWidth(
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
mainAxisSize: MainAxisSize.min,
children: const [
Expanded(
child: ChoiceChip(
label: Text('Larger Text'),
selected: false,
)),
Expanded(
child: ChoiceChip(
label: Text('Text'),
selected: false,
)),
],
))
]);
}
}
To solve this, let's start by enabling Flutter Inspector, we can see the second IntrinsicWidth width and its children don't fill their parent as the first one (two problems)
Solve 1st problem: IntrinsicWidth children don't fill their parent width
So, the problem is the size of the 2nd IntrinsicWidth's children is not wide/big enough so that it can be full of parent width. Try increasing its width manually by wrapping it in a Container with double.infinity width, like this:
ChoiceChip(
label: Container(width: double.infinity, child: Text('Larger Text')),
selected: false,
)
New result:
Solve 2nd problem: the 2nd IntrinsicWidth don't fill their parent width
Let's leave Column children can have the maximum width as it is (removing all IntrinsicWidth inside its children) and then wrap the Column by an IntrinsicWidth. Complete sample code:
Sample code
import 'package:flutter/material.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
#override
Widget build(BuildContext context) {
return const MaterialApp(
home: Scaffold(
body: MyWidget(),
),
);
}
}
class MyWidget extends StatelessWidget {
const MyWidget({super.key});
#override
Widget build(BuildContext context) {
return IntrinsicWidth(
child: Column(
children: [
Row(
mainAxisAlignment: MainAxisAlignment.center,
mainAxisSize: MainAxisSize.min,
children: [
Expanded(
child: ElevatedButton(
child: const Text('Larger Text'),
onPressed: () {},
),
),
Expanded(
child: ElevatedButton(
child: const Text('Text'),
onPressed: () {},
),
),
],
),
Row(
mainAxisAlignment: MainAxisAlignment.center,
mainAxisSize: MainAxisSize.min,
children: [
Expanded(
child: ChoiceChip(
label: Container(width: double.infinity, child: Text('Larger Text')),
selected: false,
),
),
Expanded(
child: ChoiceChip(
label: Container(width: double.infinity, child: Text('Text')),
selected: false,
),
),
],
),
],
),
);
}
}
Final result:
Because under the hood the widgets are designed differently (that's why the names).
I haven't checked the code in detail (you can do that by ctrl + click on Widget Name).
But best guess, visual density is lower in chips for being compact and higher in buttons.
More on technical difference to understand which to use : chips-vs-button

How to make this in Flutter i am new in flutter so if anyone knows

I want one row with this one big image on left and two images on right with one up and the second down.
thanks in advance if Someone can help!!
The key insight is to break the layout into nested rows and/or columns. Check out this example,
import 'package:flutter/material.dart';
void main() {
runApp(App());
}
class App extends StatefulWidget {
#override
_AppState createState() => _AppState();
}
class _AppState extends State<App> {
#override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
backgroundColor: Colors.white,
body: Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
Expanded(
child: getContainer(Colors.green),
),
Expanded(
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
Expanded(
child: getContainer(Colors.yellow),
),
Expanded(
child: getContainer(Colors.red),
)
],
),
),
],
),
),
);
}
}
Widget getContainer(MaterialColor color) =>
Container(height: 50, width: 50, color: color);
Everything is contained in one row, the first column will be larger than the second one with the widget Expanded flex :1. In the second column, there's a column widget with that you'll have two rows for your image.
import 'package:flutter/material.dart';
class Home extends StatelessWidget {
const Home({Key? key}) : super(key: key);
#override
Widget build(BuildContext context) {
return Scaffold(
body: Container(
child: Row(
children: [
Expanded(
child: SizedBox(
child: Image.asset('your large image'),
),
flex: 1,
),
Expanded(
child: Column(
children: [
Image.asset('your second image'),
Image.asset('your third image'),
],
),
flex: 0,
)
],
),
),
);
}
}
solved
**here is the example **
import 'package:flutter/material.dart';
class BagScreen extends StatelessWidget {
const BagScreen({Key key}) : super(key: key);
#override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: Container(
// color: Colors.red,
height: 400,
width: 400,
child: Row(
children: [
Container(
child: Image.asset(
"assets/images/bgimage.PNG",
fit: BoxFit.contain,
width: 250.0,
// height: 350.0,
),
),
SizedBox(
width: 10.0,
),
Column(
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: [
SizedBox(
height: 10.0,
),
Container(
child: Image.asset("assets/images/upsm.PNG"),
),
Container(
child: Image.asset("assets/images/upsm.PNG"),
),
],
)
],
),
),
),
);
}
}

Unhandled Exception: Scaffold.of() called with a context that does not contain a Scaffold

I am trying to show snackbar on button click but due to some reasons facing an error message below.
Unhandled Exception: Scaffold.of() called with a context that does not
contain a Scaffold.
Am I missing anything?
Code
class SignIn extends StatefulWidget {
#override
_SignInState createState() {
return _SignInState();
}
}
class _SignInState extends State<SignIn> {
#override
Widget build(BuildContext context) {
return MaterialApp(
title: "Hello",
home: Scaffold(
body: Center(
child: ListView(shrinkWrap: true, children: <Widget>[
Center(
child: Form(
key: _formKey,
child: Column(children: <Widget>[
Container(
child: Column(
children: <Widget>[
Container(
child: Row(
children: <Widget>[
ElevatedButton(
child: Text("Login"),
onPressed: () {
Scaffold.of(context).showSnackBar(
SnackBar(
content: Text("Hello there!"),
),
);
})
],
),
)
],
),
)
]),
))
]))));
}
}
Use Scaffold key for showing snackbar.
class SignIn extends StatefulWidget {
#override
_SignInState createState() {
return _SignInState();
}
}
class _SignInState extends State<SignIn> {
final _formKey = GlobalKey<FormState>();
final _scaffoldKey = GlobalKey<ScaffoldState>();
#override
Widget build(BuildContext context) {
return MaterialApp(
title: "Hello",
home: Scaffold(
key: _scaffoldKey,
body: Center(
child: ListView(
shrinkWrap: true,
children: <Widget>[
Center(
child: Form(
key: _formKey,
child: Column(children: <Widget>[
Container(
child: Column(
children: <Widget>[
Container(
child: Row(
children: <Widget>[
ElevatedButton(
child: Text("Login"),
onPressed: () async {
_scaffoldKey.currentState.showSnackBar(
SnackBar(
content: Text("Hello there!"),
),
);
})
],
),
)
],
),
)
]),
),
),
],
),
),
),
);
}
}
Try
Material App (home: NewWidget())
In which the
NewWidget();
is a stateless or stateful widget that returns Scaffold
Create a new widget and paste all the code from Scaffold. Then return the widget at home:

Flutter Error - Could not make the context current to acquire the frame

I'm getting the error below when I resize the app window. It doesn't crash the app nor does the frame rate drop at all. I couldn't find a whole lot on this error. Does anyone have ideas?
[ERROR:flutter/shell/gpu/gpu_surface_gl.cc(239)] Could not make the context current to acquire the frame.
class HomeScreen extends StatefulWidget {
#override
_HomeScreenState createState() => _HomeScreenState();
}
class _HomeScreenState extends State<HomeScreen> {
#override
Widget build(BuildContext context) {
return Scaffold(
body: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
Container(
child: Column(
children: [
Text('Col text 1'),
Text('Col text 2'),
Text('Col text 3'),
],
),
),
Expanded(
child: Padding(
padding: const EdgeInsets.all(8.0),
child: Center(
child: AspectRatio(
aspectRatio: 1.0,
child: Container(
color: Colors.red,
),
),
),
),
),
FlatButton(
child: Text('Reset'),
onPressed: () {},
)
],
),
);
}
}

Flutter: How to show and hide the Lottie animation

I already success to show the Lottie like below:
But the question is, how to trigger to show and hide the Lottie with a button? For example, the Lottie is not showing, but when I clicking Show Lottie button, the Lottie will show, and when I clicking Hide Lottie button, the Lottie will hide.
This is my full code:
import 'package:flutter/material.dart';
import 'package:lottie/lottie.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: Text('Lottie Flutter'),
),
body: Container(
width: double.infinity,
child: Column(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: <Widget>[
SizedBox(
width: 50,
height: 50,
child: Lottie.asset(
'assets/10219-notification-dot.json',
),
),
Row(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: <Widget>[
RaisedButton(
onPressed: () {},
child: Text('Show Lottie'),
),
RaisedButton(
onPressed: () {},
child: Text('Hide Lottie'),
),
],
),
],
),
),
),
);
}
}
use a showDialogue method.
child -> GestureDetector, which when tapped do a pop.
Code is below:
showDialog(
context: context,
builder: (context) {
return GestureDetector(
onTap: () {
Navigator.pop(context);
},
child: Lottie.asset('assets/animations/success.json',
repeat: false, animate: true),
);
});
});
I solved this with using setState and Visibility widget, this is my code:
import 'package:flutter/material.dart';
import 'package:lottie/lottie.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatefulWidget {
#override
_MyAppState createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
var _isShow = false;
#override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: Text('Lottie Flutter'),
),
body: Container(
width: double.infinity,
child: Column(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: <Widget>[
SizedBox(
width: 50,
height: 50,
child: Visibility(
visible: _isShow,
child: Lottie.asset(
'assets/10219-notification-dot.json',
),
),
),
Row(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: <Widget>[
RaisedButton(
onPressed: () {
setState(() {
_isShow = true;
});
},
child: Text('Show Lottie'),
),
RaisedButton(
onPressed: () {
setState(() {
_isShow = false;
});
},
child: Text('Hide Lottie'),
),
],
),
],
),
),
),
);
}
}
You can use a bool and if else condition to show it. Below code can give an idea perhaphs.
var show = true;
...
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
....
show ?? Lottie.asset(
'assets/10219-notification-dot.json',
),
....
RaisedButton(
onPressed: () {
setState(){show = true}
},
child: Text('Show Lottie'),
),
RaisedButton(
onPressed: () {
setState(){show = false}
},
child: Text('Hide Lottie'),
),