Flutter onChanged does not get called for any widget - radio-button

I have implemented RadioButtons in my Flutter Project and the onChanged for those RadioButtons does not get Called. I tried the same thing with TextField and CheckBox which didn't work either
main() => runApp(MyApp());
class MyApp extends StatefulWidget {
#override
State<StatefulWidget> createState() {
return MyAppState();
}
}
class MyAppState extends State<MyApp> {
#override
Widget build(BuildContext context) {
return MaterialApp(
title: "Different Widgets",
debugShowCheckedModeBanner: false,
home: _showRadioButton());
}
List<Widget> makeRadios() {
int _selected = 0;
void onChanged(int value) {
setState(() {
_selected = value;
});
}
List<Widget> list = List<Widget>();
for (int i = 0; i < 3; i++) {
list.add(Row(
children: <Widget>[
Text("Radio"),
Radio(
value: i,
groupValue: _selected,
onChanged: (int value) {
onChanged(value);
})
],
));
}
for (int i = 0; i < 3; i++) {
list.add(RadioListTile(
value: i,
groupValue: _selected,
onChanged: (int value) {
onChanged(value);
},
title: Text("title"),
activeColor: Colors.red,
secondary: Icon(Icons.access_alarm),
subtitle: Text("Gender"),
));
}
return list;
}
Widget _showRadioButton() {
return Scaffold(
appBar: AppBar(
title: Text("Hi"),
),
body: Container(
padding: EdgeInsets.all(10.0),
child: Center(
child: Column(
children:
makeRadios()
),
),
),
);
}
I don't get it why the onChanged of the radio button is not being called?
The onChanged for TextField and checkbox is also not working.

The following solution worked for me
import 'package:flutter/material.dart';
void main() {
runApp(new MaterialApp(
home: new MyApp(),
));
}
class MyApp extends StatefulWidget {
#override
MyAppState createState() => new MyAppState();
}
class MyAppState extends State<MyApp> {
int _selected = 0;
void onChanged(int value) {
setState((){
_selected = value;
});
print('Value = $value');
}
List<Widget> makeRadios() {
List<Widget> list = new List<Widget>();
for(int i = 0; i < 3; i++) {
list.add( new Row(
children: <Widget>[
new Text('Radio $i'),
new Radio(value: i, groupValue: _selected, onChanged: (int value){onChanged(value);})
],
));
}
for(int i = 0; i < 3; i++) {
list.add(new RadioListTile(
value: i,
title: new Text('Radio $i'),
groupValue: _selected,
onChanged: (int value){onChanged(value);},
activeColor: Colors.red,
secondary: new Icon(Icons.home),
subtitle: new Text('Sub Title here'),
));
}
return list;
}
#override
Widget build(BuildContext context) {
return new Scaffold(
appBar: new AppBar(
title: new Text('Radio Demo'),
),
body: new Container(
padding: new EdgeInsets.all(32.0),
child: new Center(
child: new Column(
children: makeRadios(),
),
),
),
);
}
}
I am still confused why the solution mentioned in the question did not work

Related

How to show list item to another page

From the code below, when I create user(student) data It will show up as a list. Each student information will be shown by a ListTile widget. When I slide and press the completed button on the ListTile, I want my ListTile to show on the 'Completed' page list view. I am currently working with sqlite. I am having a hard time trying to figure this out.
main.dart
import 'package:flutter/material.dart';
import '../database/db.dart';
import 'package:flutter_slidable/flutter_slidable.dart';
import 'package:crypto/crypto.dart';
import 'dart:convert';
void main() {
runApp(MyApp());
}
class MyApp extends StatefulWidget {
#override
_MyAppState createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
#override
Widget build(BuildContext context) {
return (MaterialApp(
home: Scaffold(
body: PageView(children: <Widget>[Home(), Completed()]),
)));
}
}
//Uncompleted
class Home extends StatefulWidget {
#override
_HomeState createState() => _HomeState();
}
class _HomeState extends State<Home> {
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
centerTitle: false,
title: Text("Students"),
actions: [
IconButton(
onPressed: () {
Navigator.push(
context,
MaterialPageRoute(builder: (context) => AddInfo()),
).then((value) {
setState(() {});
});
},
icon: Icon(Icons.add),
)
],
),
body: userInfoBuilder(context),
);
}
Future<List<UserInfo>> loadUserInfo() async {
DBHelper sd = DBHelper();
return await sd.userInfo();
}
Future<void> deleteUserInfo(String id) async {
DBHelper sd = DBHelper();
sd.deleteUserInfo(id);
}
Widget userInfoBuilder(BuildContext parentContext) {
return FutureBuilder<List<UserInfo>>(
builder: (context, snap) {
if (snap.data == null || snap.data.isEmpty) {
return Container();
}
return ListView.builder(
itemCount: snap.data.length,
itemBuilder: (context, index) {
UserInfo userInfo = snap.data[index];
return Slidable(
actionPane: SlidableBehindActionPane(),
actions: <Widget>[
IconSlideAction(
caption: 'delete',
icon: Icons.delete,
color: Colors.red,
onTap: () {
setState(() {
deleteUserInfo(userInfo.id);
});
})
],
secondaryActions: <Widget>[
IconSlideAction(
caption: 'completed',
icon: Icons.check,
color: Colors.green,
onTap: () {}),
],
child: ListTile(
title: Text(
userInfo.name,
style: TextStyle(
fontSize: 18.0,
),
),
trailing: Text(
'${userInfo.grade}-${userInfo.classnum}-${userInfo.studentnum}',
style: TextStyle(color: Colors.grey),
),
),
);
},
);
},
future: loadUserInfo(),
);
}
}
//completed
class Completed extends StatefulWidget {
#override
_CompletedState createState() => _CompletedState();
}
class _CompletedState extends State<Completed> {
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
centerTitle: false,
title: Text(
"Completed",
),
),
body: userInfoBuilder(context),
);
}
Widget userInfoBuilder(BuildContext parentContext) {
return FutureBuilder<List<UserInfo>>(
builder: (context, snap) {
if (snap.data == null || snap.data.isEmpty) {
return Container();
}
return ListView.builder();
},
future: loadUserInfo(),
);
}
Future<List<UserInfo>> loadUserInfo() async {
DBHelper sd = DBHelper();
return await sd.userInfo();
}
}
//Add user information
class AddInfo extends StatefulWidget {
#override
_AddInfoState createState() => _AddInfoState();
}
class _AddInfoState extends State<AddInfo> {
hideKeyboard() {
FocusScopeNode currentFocus = FocusScope.of(context);
if (!currentFocus.hasPrimaryFocus) {
currentFocus.unfocus();
}
}
final formKey = GlobalKey<FormState>();
String _grade;
final List<String> _grades = ['1', '2', '3'];
String name = '';
String classNum = ' ';
String studentNum = ' ';
#override
Widget build(BuildContext context) {
return GestureDetector(
onTap: () {
hideKeyboard();
},
child: Scaffold(
appBar: AppBar(
leading: IconButton(
icon: Icon(Icons.arrow_back),
color: Colors.black,
onPressed: () {
Navigator.pop(context);
hideKeyboard();
})),
body: Form(
key: formKey,
child: Column(
children: <Widget>[
usrNameField(),
Row(
children: <Widget>[
Expanded(child: usrGradeField()),
Padding(
padding: EdgeInsets.symmetric(horizontal: 20.0),
),
Expanded(child: usrClassField()),
Padding(
padding: EdgeInsets.symmetric(horizontal: 20.0),
),
Expanded(child: usrNumField()),
],
),
submitButton()
],
),
),
));
}
Widget usrNameField() {
return TextFormField(
keyboardType: TextInputType.name,
decoration: InputDecoration(
labelText: 'name',
),
onChanged: (String name) {
this.name = name;
},
validator: (input) => input.trim().isEmpty ? 'Enter name' : null);
}
Widget usrGradeField() {
return DropdownButtonFormField(
icon: Icon(Icons.arrow_drop_down_circle),
iconSize: 22.0,
items: _grades.map((String grade) {
return DropdownMenuItem(
value: grade,
child: Text(
grade,
style: TextStyle(color: Colors.black, fontSize: 18.0),
),
);
}).toList(),
style: TextStyle(fontSize: 18.0),
decoration: InputDecoration(
labelText: 'Grade',
),
validator: (input) => input.trim().isEmpty ? 'Enter grade.' : null,
onChanged: (value) {
setState(() {
_grade = value;
});
},
value: _grade,
);
}
Widget usrClassField() {
return TextFormField(
keyboardType: TextInputType.number,
decoration: InputDecoration(
labelText: 'Class',
),
validator: (input) => input.trim().isEmpty ? 'Enter class.' : null,
onChanged: (String classNum) {
this.classNum = classNum;
},
);
}
Widget usrNumField() {
return TextFormField(
keyboardType: TextInputType.number,
decoration: InputDecoration(
labelText: 'Number',
),
validator: (input) => input.trim().isEmpty ? 'Enter number' : null,
onChanged: (String studentNum) {
this.studentNum = studentNum;
},
);
}
Widget submitButton() {
return MaterialButton(
color: Colors.blue,
child: Text(
'submit',
style: TextStyle(color: Colors.white),
),
onPressed: () {
hideKeyboard();
if (formKey.currentState.validate()) {
saveDB();
Navigator.pop(context);
}
},
);
}
Future<void> saveDB() async {
DBHelper sd = DBHelper();
var fido = UserInfo(
id: str2sha512(DateTime.now().toString()),
name: this.name,
grade: this._grade,
classnum: this.classNum,
studentnum: this.studentNum,
);
await sd.insertUserInfo(fido);
print(await sd.userInfo());
}
String str2sha512(String text) {
var bytes = utf8.encode(text);
var digest = sha512.convert(bytes);
return digest.toString();
}
}
db.dart
import 'dart:async';
import 'package:path/path.dart';
import 'package:sqflite/sqflite.dart';
class UserInfo {
final String id;
final String name;
final String grade;
final String classnum;
final String studentnum;
UserInfo({
this.id,
this.name,
this.grade,
this.classnum,
this.studentnum,
});
Map<String, dynamic> toMap() {
return {
'id': id,
'name': name,
'grade': grade,
'classnum': classnum,
'studentnum': studentnum,
};
}
#override
String toString() {
return 'userInfo{id: $id, name: $name, grade: $grade, classnum: $classnum, studentnum: $studentnum}';
}
}
final String TableName = 'userInfo';
class DBHelper {
var _db;
Future<Database> get database async {
if (_db != null) return _db;
_db = openDatabase(
join(await getDatabasesPath(), 'userInfo.db'),
onCreate: (db, version) {
return db.execute(
"CREATE TABLE userInfo(id TEXT PRIMARY KEY, name TEXT, grade TEXT, classnum TEXT, studentnum TEXT, phonenumber TEXT, status INTEGER)",
);
},
version: 1,
);
return _db;
}
Future<void> insertUserInfo(UserInfo userInfo) async {
final db = await database;
await db.insert(
TableName,
userInfo.toMap(),
conflictAlgorithm: ConflictAlgorithm.replace,
);
}
Future<List<UserInfo>> userInfo() async {
final db = await database;
final List<Map<String, dynamic>> maps = await db.query('userInfo');
return List.generate(maps.length, (i) {
return UserInfo(
id: maps[i]['id'],
name: maps[i]['name'],
grade: maps[i]['grade'],
classnum: maps[i]['classnum'],
studentnum: maps[i]['studentnum'],
);
});
}
Future<void> updateUserInfo(UserInfo userInfo) async {
final db = await database;
await db.update(
TableName,
userInfo.toMap(),
where: "id = ?",
whereArgs: [userInfo.id],
);
}
Future<void> deleteUserInfo(String id) async {
final db = await database;
await db.delete(
TableName,
where: "id = ?",
whereArgs: [id],
);
}
}
You can use the Provider package to listen to changes on your app and notify any listeners and update the UI here's A link to an example from the flutter devs

Flutter Http Request is returning null

I am trying to make some http requests to an API. The first is to get data and display it in a list view and the second one is some more data but I want to display it on a new page. The code I have currently is returning null for the second Total request. If I run the total code separately it works fine and displays the data in a list view.
main.dart
import 'package:flutter/material.dart';
import 'dart:async';
import 'dart:convert';
import 'package:http/http.dart' as http;
import 'Product.dart';
import 'Total.dart';
void main() => runApp(MyApp(
products: fetchProducts(),
total: fetchTotal(),
));
List<Product> parseProducts(String responseBody) {
final parsed = json.decode(responseBody).cast<Map<String, dynamic>>();
return parsed.map<Product>((json) => Product.fromJson(json)).toList();
}
Future<List<Product>> fetchProducts() async {
final response =
await http.get('http://10.0.0.102:9000/all/aF63z0R0jlQR7sfOgBAgOCOsQgv1');
if (response.statusCode == 200) {
return parseProducts(response.body);
} else {
throw Exception("Unable to access Server.");
}
}
class MyApp extends StatelessWidget {
final Future<List<Product>> products;
final Future<List<Total>> total;
MyApp({Key key, this.products, this.total}) : super(key: key);
// This widget is the root of your application.
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: MyHomePage(
title: 'Product Navigation demo home page',
products: products,
),
);
}
}
class MyHomePage extends StatelessWidget {
final String title;
final Future<List<Product>> products;
final Future<List<Total>> total;
MyHomePage({Key key, this.title, this.products, this.total})
: super(key: key);
// final items = Product.getProducts();
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text("Product Navigation")),
body: Center(
child: FutureBuilder<List<Product>>(
future: products,
builder: (context, snapshot) {
if (snapshot.hasError) print(snapshot.error);
return snapshot.hasData
? ProductBoxList(items: snapshot.data)
// return the ListView widget :
: Center(child: CircularProgressIndicator());
},
),
),
floatingActionButton: FloatingActionButton(
onPressed: () {
Navigator.push(
context, MaterialPageRoute(builder: (context) => TotalPage()));
},
child: Icon(Icons.navigation),
backgroundColor: Colors.green,
),
);
}
}
class ProductBoxList extends StatelessWidget {
final List<Product> items;
ProductBoxList({Key key, this.items});
#override
Widget build(BuildContext context) {
return ListView.builder(
itemCount: items.length,
itemBuilder: (context, index) {
return GestureDetector(
child: ProductBox(item: items[index]),
onTap: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => ProductPage(item: items[index]),
),
);
},
);
},
);
}
}
class ProductPage extends StatelessWidget {
ProductPage({Key key, this.item}) : super(key: key);
final Product item;
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(this.item.pName),
),
body: Center(
child: Container(
padding: EdgeInsets.all(0),
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Expanded(
child: Container(
padding: EdgeInsets.all(5),
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: <Widget>[
Text(this.item.pName,
style: TextStyle(fontWeight: FontWeight.bold)),
Text("Price: " + this.item.price),
Text("Barcode: " + this.item.barcode.toString()),
],
)))
]),
),
),
);
}
}
class ProductBox extends StatelessWidget {
ProductBox({Key key, this.item}) : super(key: key);
final Product item;
Widget build(BuildContext context) {
return Container(
padding: EdgeInsets.all(2),
height: 140,
child: Card(
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: <Widget>[
Expanded(
child: Container(
padding: EdgeInsets.all(5),
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: <Widget>[
Text(this.item.pName,
style: TextStyle(fontWeight: FontWeight.bold)),
Text("Price: " + this.item.price),
Text("Barcode: " + this.item.barcode.toString()),
],
)))
]),
));
}
}
List<Total> parseTotal(String responseBody) {
final parsed = json.decode(responseBody).cast<Map<String, dynamic>>();
return parsed.map<Total>((json) => Total.fromJson(json)).toList();
}
Future<List<Total>> fetchTotal() async {
final response = await http.get('http://10.0.0.102:8000/testData.json');
if (response.statusCode == 200) {
return parseTotal(response.body);
} else {
throw Exception("Unable to access Server.");
}
}
class TotalPage extends StatelessWidget {
final String title;
final Future<List<Total>> total;
TotalPage({Key key, this.title, this.total}) : super(key: key);
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text("Product Navigation")),
body: Center(
child: FutureBuilder<List<Total>>(
future: total,
builder: (context, snapshot) {
if (snapshot.hasError) print(snapshot.error);
print(snapshot.data);
return snapshot.hasData
? TotalBoxList(items: snapshot.data)
// return the ListView widget :
: Center(child: CircularProgressIndicator());
},
),
),
);
}
}
class TotalBoxList extends StatelessWidget {
final List<Total> items;
TotalBoxList({Key key, this.items});
#override
Widget build(BuildContext context) {
return ListView.builder(
itemCount: items.length,
itemBuilder: (context, index) {
return GestureDetector(
child: TotalDisplay(item: items[index]),
);
},
);
}
}
class TotalDisplay extends StatelessWidget {
TotalDisplay({Key key, this.item}) : super(key: key);
final Total item;
Widget build(BuildContext context) {
return Container(
padding: EdgeInsets.all(2),
height: 140,
child: Card(
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: <Widget>[
Expanded(
child: Container(
padding: EdgeInsets.all(5),
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: <Widget>[
Text(this.item.total.toString(),
style: TextStyle(fontWeight: FontWeight.bold)),
],
)))
]),
));
}
}
total.dart
import 'package:flutter/foundation.dart';
class Total {
final double total;
Total(this.total);
factory Total.fromJson(Map<String, dynamic> data) {
return Total(
data['total'],
);
}
}
You can copy paste run full code below
You forgot to pass total
Step 1: MyHomePage
MyHomePage(
title: 'Product Navigation demo home page',
products: products,
total: total, //here
),
Step 2: FloatingActionButton
floatingActionButton: FloatingActionButton(
onPressed: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => TotalPage(
total: total,
))); //here
},
working demo
full code
import 'package:flutter/material.dart';
import 'dart:async';
import 'dart:convert';
import 'package:http/http.dart' as http;
void main() => runApp(MyApp(
products: fetchProducts(),
total: fetchTotal(),
));
List<Product> parseProducts(String responseBody) {
final parsed = json.decode(responseBody).cast<Map<String, dynamic>>();
return parsed.map<Product>((json) => Product.fromJson(json)).toList();
}
Future<List<Product>> fetchProducts() async {
/*final response =
await http.get('http://10.0.0.102:9000/all/aF63z0R0jlQR7sfOgBAgOCOsQgv1');*/
String jsonString = '''
[
{
"pName":"1",
"price":"2",
"barcode": 3
},
{
"pName":"4",
"price":"5",
"barcode": 6
}
]
''';
final response = http.Response(jsonString, 200);
if (response.statusCode == 200) {
return parseProducts(response.body);
} else {
throw Exception("Unable to access Server.");
}
}
class MyApp extends StatelessWidget {
final Future<List<Product>> products;
final Future<List<Total>> total;
MyApp({Key key, this.products, this.total}) : super(key: key);
// This widget is the root of your application.
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: MyHomePage(
title: 'Product Navigation demo home page',
products: products,
total: total, //here
),
);
}
}
class MyHomePage extends StatelessWidget {
final String title;
final Future<List<Product>> products;
final Future<List<Total>> total;
MyHomePage({Key key, this.title, this.products, this.total})
: super(key: key);
// final items = Product.getProducts();
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text("Product Navigation")),
body: Center(
child: FutureBuilder<List<Product>>(
future: products,
builder: (context, snapshot) {
if (snapshot.hasError) print(snapshot.error);
return snapshot.hasData
? ProductBoxList(items: snapshot.data)
// return the ListView widget :
: Center(child: CircularProgressIndicator());
},
),
),
floatingActionButton: FloatingActionButton(
onPressed: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => TotalPage(
total: total,
))); //here
},
child: Icon(Icons.navigation),
backgroundColor: Colors.green,
),
);
}
}
class ProductBoxList extends StatelessWidget {
final List<Product> items;
ProductBoxList({Key key, this.items});
#override
Widget build(BuildContext context) {
return ListView.builder(
itemCount: items.length,
itemBuilder: (context, index) {
return GestureDetector(
child: ProductBox(item: items[index]),
onTap: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => ProductPage(item: items[index]),
),
);
},
);
},
);
}
}
class ProductPage extends StatelessWidget {
ProductPage({Key key, this.item}) : super(key: key);
final Product item;
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(this.item.pName),
),
body: Center(
child: Container(
padding: EdgeInsets.all(0),
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Expanded(
child: Container(
padding: EdgeInsets.all(5),
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: <Widget>[
Text(this.item.pName,
style: TextStyle(fontWeight: FontWeight.bold)),
Text("Price: " + this.item.price),
Text("Barcode: " + this.item.barcode.toString()),
],
)))
]),
),
),
);
}
}
class ProductBox extends StatelessWidget {
ProductBox({Key key, this.item}) : super(key: key);
final Product item;
Widget build(BuildContext context) {
return Container(
padding: EdgeInsets.all(2),
height: 140,
child: Card(
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: <Widget>[
Expanded(
child: Container(
padding: EdgeInsets.all(5),
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: <Widget>[
Text(this.item.pName,
style: TextStyle(fontWeight: FontWeight.bold)),
Text("Price: " + this.item.price),
Text("Barcode: " + this.item.barcode.toString()),
],
)))
]),
));
}
}
List<Total> parseTotal(String responseBody) {
final parsed = json.decode(responseBody).cast<Map<String, dynamic>>();
List<Total> a = parsed.map<Total>((json) => Total.fromJson(json)).toList();
return a;
}
Future<List<Total>> fetchTotal() async {
print("fetchTotal");
//final response = await http.get('http://10.0.0.102:8000/testData.json');
String jsonString = '''
[
{
"total":124.4
},
{
"total":123.1
}
]
''';
final response = http.Response(jsonString, 200);
if (response.statusCode == 200) {
return parseTotal(response.body);
} else {
throw Exception("Unable to access Server.");
}
}
class TotalPage extends StatelessWidget {
final String title;
final Future<List<Total>> total;
TotalPage({Key key, this.title, this.total}) : super(key: key);
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text("Product Navigation")),
body: Center(
child: FutureBuilder<List<Total>>(
future: total,
builder: (context, snapshot) {
if (snapshot.hasError) print(snapshot.error);
return snapshot.hasData
? TotalBoxList(items: snapshot.data)
// return the ListView widget :
: Center(child: CircularProgressIndicator());
},
),
),
);
}
}
class TotalBoxList extends StatelessWidget {
final List<Total> items;
TotalBoxList({Key key, this.items});
#override
Widget build(BuildContext context) {
return ListView.builder(
itemCount: items.length,
itemBuilder: (context, index) {
return GestureDetector(
child: TotalDisplay(item: items[index]),
);
},
);
}
}
class TotalDisplay extends StatelessWidget {
TotalDisplay({Key key, this.item}) : super(key: key);
final Total item;
Widget build(BuildContext context) {
return Container(
padding: EdgeInsets.all(2),
height: 140,
child: Card(
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: <Widget>[
Expanded(
child: Container(
padding: EdgeInsets.all(5),
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: <Widget>[
Text(this.item.total.toString(),
style: TextStyle(fontWeight: FontWeight.bold)),
],
)))
]),
));
}
}
class Total {
final double total;
Total(this.total);
factory Total.fromJson(Map<String, dynamic> data) {
return Total(
data['total'],
);
}
}
class Product {
String pName;
String price;
int barcode;
Product({this.pName, this.price, this.barcode});
factory Product.fromJson(Map<String, dynamic> data) {
return Product(
pName: data["pName"], price: data["price"], barcode: data["barcode"]);
}
}

Error fetching data from api and display it

I want to make a get request from my restApi and then display the data in a listView but for some reason it is not working.
The error I'm getting:
The getter 'length' was called on null.
Receiver: null
Tried calling: length
Api call (apiBaseHelper.dart)
Future<List<Post>> getAllPosts() async {
final prefs = await SharedPreferences.getInstance();
final key = 'token';
final value = prefs.get(key) ?? 0;
final getPublishedPostUrl = "http://192.168.1.7:5000/post/all";
final response = await http.get(getPublishedPostUrl, headers: {
'Accept': 'application/json',
'Authorization': 'Bearer $value'
});
if (response.statusCode == 200) {
List jsonResponse = json.decode(response.body);
return jsonResponse.map((posts) => new Post.fromJson(posts)).toList();
} else {
throw "something ";
}
}
PostListView
class PostListView extends StatelessWidget {
final List<Post> posts;
PostListView({Key key, this.posts}) : super(key: key);
#override
Widget build(BuildContext context) {
return Scaffold(
body: ListView.builder(
itemCount: posts.length,
itemBuilder: (context, index) {
return Column(
children: <Widget>[
Container(
constraints: BoxConstraints.expand(
height:
Theme.of(context).textTheme.display1.fontSize * 1.1 + 200.0,
),
color: Colors.white10,
alignment: Alignment.center,
child: Card(
child: Column(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
ListTile(
contentPadding: EdgeInsets.all(10.0),
title: new Text(posts[index].title),
leading: new Image.network(
posts[index].picture,
fit: BoxFit.cover,
height: 40.0,
width: 40.0,
),
subtitle: Text(posts[index].category),
),
],
),
),
),
],
);
},
));
}
}
homePage.dart
class HomePage extends StatefulWidget {
final ApiBaseHelper apiBaseHelper = ApiBaseHelper();
#override
State<StatefulWidget> createState() {
return _HomePageState();
}
}
class _HomePageState extends State<HomePage> {
Future<List<Post>> futurePost;
#override
void initState() {
super.initState();
futurePost = ApiBaseHelper().getAllPosts();
}
#override
Widget build(BuildContext context) {
return new Scaffold(
backgroundColor: Colors.teal,
body: new Padding(
padding: EdgeInsets.fromLTRB(1.0, 10.0, 1.0, 10.0),
child: FutureBuilder<List<Post>>(
future: ApiBaseHelper().getAllPosts(),
builder: (context, AsyncSnapshot<List<Post>> snapshot) {
if (snapshot.hasError) {
print(snapshot.error);
}
return snapshot.hasData
? PostListView()
: Center(child: CircularProgressIndicator());
},
),
),
);
}
}
I have been working on it for like 2 days and I don't know where the problem exactly
I'm sorry if it's too much code. thank you in advance
This code section here ,
return snapshot.hasData
? PostListView()
: Center(child: CircularProgressIndicator());
Add PostListView(posts:snapshot.data)
Tell me if it works.

How do I deal with logins on different devices based on API response in flutter?

I'm confused about how to deal with multiple logins with different devices, and I want to give the function back to the login layout when there are other devices that have just logged in to the same user
Future<EventArticleList> getEventArticleList(String token) async {
BuildContext context;
Map<String, String> headers = {
"Accept": "application/json",
"Authorization": "Bearer $token"
};
var response = await client.get('$endpoint/', headers: headers);
if (response.statusCode == 200) {
print("Masuk Data");
return EventArticleList.fromJson(
json.decode(response.body),
);
} else if (response.statusCode == 401) {
print("401");
return Navigator.of(context)
.pushNamedAndRemoveUntil(RoutePaths.Login, (_) => false);
} else {
throw Exception("ini Eror apa ?");
}
}
the compilation appears I try to add the navigator back to status.code == 401
NoSuchMethodError: The method 'ancestorStateOfType' was called on null
Try this code
Your main class
import 'package:flutter/material.dart';
import 'package:flutterapitut/view/adddata.dart';
import 'package:flutterapitut/view/dashboard.dart';
import 'package:flutterapitut/view/login.dart';
import 'package:flutterapitut/view/register.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
final String title='';
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter CRUD API',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: LoginPage(title: 'Flutter CRUD API'),
routes: <String,WidgetBuilder>{
'/dashboard' : (BuildContext context) => new Dashboard(title:title),
'/login' : (BuildContext context) => new LoginPage(title:title),
},
);
}
}
Your Database Helper class
import 'package:http/http.dart' as http;
import 'dart:convert';
import 'package:shared_preferences/shared_preferences.dart';
class DatabaseHelper{
String serverUrl = "http://flutterapitutorial.codeforiraq.org/api";
var status ;
var token ;
loginData(String email , String password) async{
String myUrl = "$serverUrl/login1";
final response = await http.post(myUrl,
headers: {
'Accept':'application/json'
},
body: {
"email": "$email",
"password" : "$password"
} ) ;
status = response.body.contains('error');
var data = json.decode(response.body);
if(status){
print('data : ${data["error"]}');
}else{
print('data : ${data["token"]}');
_save(data["token"]);
}
}
_save(String token) async {
final prefs = await SharedPreferences.getInstance();
final key = 'token';
final value = token;
prefs.setString(key, value);
}
read() async {
final prefs = await SharedPreferences.getInstance();
final key = 'token';
final value = prefs.get(key ) ?? 0;
print('read : $value');
}
}
Your login class
import 'package:flutter/material.dart';
import 'package:flutterapitut/Controllers/databasehelper.dart';
import 'package:flutterapitut/view/dashboard.dart';
import 'package:flutterapitut/view/register.dart';
import 'package:shared_preferences/shared_preferences.dart';
class LoginPage extends StatefulWidget{
LoginPage({Key key , this.title}) : super(key : key);
final String title;
#override
LoginPageState createState() => LoginPageState();
}
class LoginPageState extends State<LoginPage> {
read() async {
final prefs = await SharedPreferences.getInstance();
final key = 'token';
final value = prefs.get(key ) ?? 0;
if(value != '0'){
Navigator.of(context).push(
new MaterialPageRoute(
builder: (BuildContext context) => new Dashboard(),
)
);
}
}
#override
initState(){
read();
}
DatabaseHelper databaseHelper = new DatabaseHelper();
String msgStatus = '';
final TextEditingController _emailController = new TextEditingController();
final TextEditingController _passwordController = new TextEditingController();
_onPressed(){
setState(() {
if(_emailController.text.trim().toLowerCase().isNotEmpty &&
_passwordController.text.trim().isNotEmpty ){
databaseHelper.loginData(_emailController.text.trim().toLowerCase(),
_passwordController.text.trim()).whenComplete((){
if(databaseHelper.status){
_showDialog();
msgStatus = 'Check email or password';
}else{
Navigator.pushReplacementNamed(context, '/dashboard');
}
});
}
});
}
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Login',
home: Scaffold(
appBar: AppBar(
title: Text('Login'),
),
body: Container(
child: ListView(
padding: const EdgeInsets.only(top: 62,left: 12.0,right: 12.0,bottom: 12.0),
children: <Widget>[
Container(
height: 50,
child: new TextField(
controller: _emailController,
keyboardType: TextInputType.emailAddress,
decoration: InputDecoration(
labelText: 'Email',
hintText: 'Place your email',
icon: new Icon(Icons.email),
),
),
),
Container(
height: 50,
child: new TextField(
controller: _passwordController,
keyboardType: TextInputType.text,
decoration: InputDecoration(
labelText: 'Password',
hintText: 'Place your password',
icon: new Icon(Icons.vpn_key),
),
),
),
new Padding(padding: new EdgeInsets.only(top: 44.0),),
Container(
height: 50,
child: new RaisedButton(
onPressed: _onPressed,
color: Colors.blue,
child: new Text(
'Login',
style: new TextStyle(
color: Colors.white,
backgroundColor: Colors.blue),),
),
),
new Padding(padding: new EdgeInsets.only(top: 44.0),),
Container(
height: 50,
child: new Text(
'$msgStatus',
textAlign: TextAlign.center,
overflow: TextOverflow.ellipsis,
style: TextStyle(fontWeight: FontWeight.bold),
),
),
new Padding(padding: new EdgeInsets.only(top: 44.0),),
Container(
height: 50,
child: new FlatButton(
onPressed: ()=>Navigator.of(context).push(
new MaterialPageRoute(
builder: (BuildContext context) => new RegisterPage(),
)
)
,
color: Colors.blue,
child: new Text(
'Register',
style: new TextStyle(
color: Colors.white,
),),
),
),
],
),
),
),
);
}
void _showDialog(){
showDialog(
context:context ,
builder:(BuildContext context){
return AlertDialog(
title: new Text('Failed'),
content: new Text('Check your email or password'),
actions: <Widget>[
new RaisedButton(
child: new Text(
'Close',
),
onPressed: (){
Navigator.of(context).pop();
},
),
],
);
}
);
}
}
Here Dashboard is the class you expected to navigate after successfully login
Want more code visite here I hope this work correctly

Flutter Slider in BottomNavigationBar does not update

Using Flutter. I create a Slider Widget in a child of a BottomNavigationBar-Widget. There is its onChanged function defined, which should change the value of the Slider.
If I put the Slider in a simple Scaffold Widget it works fine.
How do I make this work in a BottomNavigationBar?
Is there anything missing (a listener/callback or something) I have to declare in the BottomNavigationBar-Widget?
I am using the Flutter stable channel with Android Studio 3.1.4.
It follows the non-working code. There is also a widget whithout the BottomNavigationBar, where the slider works as intended.
import 'package:flutter/material.dart';
void main() => runApp(new MyApp());
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return new MaterialApp(
title: 'Flutter Issue Slider in BottomNavigationBar',
theme: new ThemeData(
primarySwatch: Colors.blue,
),
home: new SliderInNavigationBar(),
// home: new MyHomePage(),
);
}
}
class SliderInNavigationBar extends StatefulWidget {
#override
State<StatefulWidget> createState() {
return new _SliderInNavigationBarScreenState();
}
}
class _SliderInNavigationBarScreenState extends State<SliderInNavigationBar> {
int _currentIndex = 0;
List<Widget> _children;
int _period = 0;
#override
void initState() {
super.initState();
_children = [
new Slider(
value: _period.toDouble(),
min: 0.0,
max: 100.0,
onChanged: (double value) {
print('OnChanged');
setState(() {
_period = value.round();
});
}),
];
}
#override
Widget build(BuildContext context) {
return new Scaffold(
appBar: new AppBar(
title: new Text('Slider in BottomNavigationBar'),
),
body: _children[_currentIndex],
bottomNavigationBar: new BottomNavigationBar(
currentIndex: _currentIndex,
type: BottomNavigationBarType.fixed,
items: [
new BottomNavigationBarItem(
icon: Icon(Icons.timelapse),
title: Text('Page 1'),
),
new BottomNavigationBarItem(
icon: Icon(Icons.message),
title: Text('Page 2'),
),
],
),
);
}
}
class MyHomePage extends StatefulWidget {
MyHomePage({Key key}) : super(key: key);
#override
_MyHomePageState createState() => new _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
int _period = 0;
#override
Widget build(BuildContext context) {
return new Scaffold(
appBar: new AppBar(
title: new Text("Slider in AppBar"),
),
body: new Center(
child: new Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
new Slider(
value: _period.toDouble(),
min: 0.0,
max: 100.0,
onChanged: (double value) {
print('OnChanged');
setState(() {
_period = value.round();
});
}),
],
),
),
);
}
}
Short Flutter doctor output:
flutter doctor
Doctor summary (to see all details, run flutter doctor -v):
[√] Flutter (Channel beta, v0.5.1, on Microsoft Windows [Version 10.0.17134.228], locale de-DE)
[√] Android toolchain - develop for Android devices (Android SDK 27.0.3)
[√] Android Studio (version 2.3)
[√] Android Studio (version 3.1)
[!] VS Code, 64-bit edition (version 1.24.1)
[√] Connected devices (1 available)
! Doctor found issues in 1 category.
Good afternoon,
You have to declared the Slider directly in the body not as a List<Widget> instantiated in the initState().
The following code should work :)
import 'package:flutter/material.dart';
void main() => runApp(new MyApp());
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return new MaterialApp(
title: 'Flutter Issue Slider in BottomNavigationBar',
theme: new ThemeData(
primarySwatch: Colors.blue,
),
home: new SliderInNavigationBar(),
// home: new MyHomePage(),
);
}
}
class SliderInNavigationBar extends StatefulWidget {
#override
State<StatefulWidget> createState() {
return new _SliderInNavigationBarScreenState();
}
}
class _SliderInNavigationBarScreenState extends State<SliderInNavigationBar> {
int _currentIndex = 0;
//List<Widget> _children;
int _period = 0;
#override
void initState() {
super.initState();
/**
_children = [
new Slider(
value: _period.toDouble(),
min: 0.0,
max: 100.0,
onChanged: (double value) {
print('OnChanged');
setState(() {
_period = value.round();
});
}),
];**/
}
#override
Widget build(BuildContext context) {
return new Scaffold(
appBar: new AppBar(
title: new Text('Slider in BottomNavigationBar'),
),
body: new Slider(
value: _period.toDouble(),
min: 0.0,
max: 100.0,
onChanged: (double value) {
print('OnChanged');
setState(() {
_period = value.round();
});
}),
bottomNavigationBar: new BottomNavigationBar(
currentIndex: _currentIndex,
type: BottomNavigationBarType.fixed,
items: [
new BottomNavigationBarItem(
icon: Icon(Icons.timelapse),
title: Text('Page 1'),
),
new BottomNavigationBarItem(
icon: Icon(Icons.message),
title: Text('Page 2'),
),
],
),
);
}
}
I commented the code that was wrong.