Flutter Slider in BottomNavigationBar does not update - slider

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.

Related

The box "name" is already open and of type Box<dynamic>

The error is The box "todo_box" is already open and of type Box.
The relevant error-causing widget was: MyHomePage MyHomePage:file:///D:/Flutter_app/alimi_final/lib/schedule.dart:27:13
When the exception was thrown, this was the stack:
I have no idea about this error.
my code
main.dart
import 'package:hive/hive.dart';
import 'dart:io';
import 'package:path_provider/path_provider.dart';
import 'package:work_a/map.dart';
import 'package:work_a/schedule.dart';
import 'package:flutter/material.dart';
import 'package:hive/hive.dart';
import 'package:work_a/boxes.dart';
import 'package:work_a/model/todo.dart';
import 'package:work_a/screens/list_screen.dart';
import 'package:hive_flutter/hive_flutter.dart';
//const bool kIsWeb = identical(0, 0.0);
//Future<Box> openHiveBox(todo_box) async {
//if (!kIsWeb && !Hive.isBoxOpen(todo_box))
//Hive.init((await getApplicationDocumentsDirectory()).path);
//return await Hive.openBox(todo_box);
//}
Future<void> main() async{
WidgetsFlutterBinding.ensureInitialized();
final appDocumentDirectory = await getApplicationDocumentsDirectory();
Hive.init(appDocumentDirectory.path);
await Hive.initFlutter();
Hive.registerAdapter(TodoAdapter());
await Hive.openBox('todo_box');
runApp(MyApp());
}
class MyApp extends StatefulWidget {
const MyApp({Key? key}) : super(key: key);
#override
State<MyApp> createState() => _alimihomeState();
}
class _alimihomeState extends State<MyApp> {
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'allimi',
theme: ThemeData(primaryColor: Colors.blue),
home: MyAppBar(),
debugShowCheckedModeBanner: false,
);
}
}
class MyAppBar extends StatelessWidget {
const MyAppBar({Key? key}) : super(key: key);
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('알리미'),
backgroundColor: Color.fromRGBO(31, 39, 76, 1.0),
centerTitle: true,
elevation: 0.0,
),
drawer: Drawer(
child: ListView(
children: [
UserAccountsDrawerHeader(
currentAccountPicture: CircleAvatar(
backgroundImage: AssetImage('images/userimage.jpg'),
),
accountName: Text('한동대생'),
accountEmail: Text('00000000#handong.ac.kr'),
decoration: BoxDecoration(
color: Color.fromRGBO(31, 39, 76, 1.0),
borderRadius: BorderRadius.only(
bottomLeft: Radius.circular(30.0),
bottomRight: Radius.circular(30.0),
),
),
),
ListTile(
leading: Icon(
Icons.circle,
color: Colors.black,
size: 10.0,
),
visualDensity: VisualDensity(vertical: -3),
horizontalTitleGap: 1.0,
title: Text('내 스케줄'),
onTap: (){
Navigator.push(
context,
MaterialPageRoute(builder: (context) => schedule()),
);
},
),
SizedBox(
height: 5.0,
),
ListTile(
leading: Icon(
Icons.circle,
color: Colors.black,
size: 10.0,
),
visualDensity: VisualDensity(vertical: -3),
horizontalTitleGap: 1.0,
title: Text('지도 보기'),
onTap: (){
Navigator.push(
context,
MaterialPageRoute(builder: (context) => MyMap()),
);
},
),
SizedBox(
height: 5.0,
),
ListTile(
leading: Icon(
Icons.circle,
color: Colors.black,
size: 10.0,
),
visualDensity: VisualDensity(vertical: -3),
horizontalTitleGap: 1.0,
title: Text('설정'),
onTap: (){},
),
SizedBox(
height: 295.0,
),
],
),
),
body: Center(
child: Column(
children: [
SizedBox(
height: 70.0,
),
CircleAvatar(
radius: 90.0,
backgroundColor: Colors.white,
backgroundImage: AssetImage('images/logoimage.jpg'),
),
SizedBox(
height: 30.0,
),
Text(
'한동 알리미',
style: TextStyle(
fontSize: 30.0,
fontWeight: FontWeight.bold,
),
),
SizedBox(
height: 210.0,
),
Text(
'DADAEGEEDEUL',
style: TextStyle(
fontSize: 10.0,
),
),
],
),
),
);
}
}
schedule.dart
import 'package:hive/hive.dart';
import 'package:work_a/boxes.dart';
import 'package:work_a/model/todo.dart';
import 'package:work_a/screens/list_screen.dart';
import 'package:hive_flutter/hive_flutter.dart';
// void main() => runApp(MyApp());
//void main() async {
//// hive initialization
//await Hive.initFlutter();
//Hive.registerAdapter(TodoAdapter());
////await Hive.openBox<Todo>(HiveBoxes.todo);
//}
class schedule extends StatelessWidget {
const schedule({Key? key}) : super(key: key);
static final String title = 'Hive Tutorial';
#override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
theme: ThemeData(
primarySwatch: Colors.blue
),
home: MyHomePage(
title: '스케줄',
),
);
}
}
list_screen.dart
import 'package:hive/hive.dart';
import 'package:work_a/boxes.dart';
import 'package:work_a/model/todo.dart';
import 'package:work_a/screens/add_todo_Screen.dart';
import 'package:hive_flutter/hive_flutter.dart';
class MyApp extends StatefulWidget {
#override
_MyAppState createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
#override
Widget build(BuildContext context) {
return MaterialApp(
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: MyHomePage(title: 'Todo Hive Example'),
);
}
}
class MyHomePage extends StatefulWidget {
MyHomePage({Key? key, required this.title}) : super(key: key);
final String title;
#override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
#override
void dispose() async {
Hive.close();
super.dispose();
//await Hive.openBox<Todo>(HiveBoxes.todo);
//await Hive.openBox<dynamic>('todo_box');
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
backgroundColor: Color.fromRGBO(31, 39, 76, 1.0),
title: Text(widget.title),
),
body: ValueListenableBuilder(
valueListenable: Hive.box<Todo>(HiveBoxes.todo).listenable(),
builder: (context, Box<Todo> box, _) {
if (box.values.isEmpty)
return Center(
child: Text("리스트가 비었습니다"),
);
return ListView.builder(
itemCount: box.values.length,
itemBuilder: (context, index) {
Todo? res = box.getAt(index);
return Dismissible(
background: Container(color: Colors.red),
key: UniqueKey(),
onDismissed: (direction) {
res!.delete();
},
child: ListTile(
title: Text(res!.title),
subtitle: Text(res.description),
onTap: () {}),
);
},
);
}),
floatingActionButton: FloatingActionButton(
tooltip: 'Add todo',
child: Icon(Icons.add),
backgroundColor: Color.fromRGBO(31, 39, 76, 1.0),
onPressed: () => Navigator.of(context).push(
MaterialPageRoute(
builder: (context) => AddTodoScreen(),
),
),
),
);
}
}
add_todo_screen.dart
import 'package:hive/hive.dart';
import 'package:work_a/boxes.dart';
import 'package:work_a/model/todo.dart';
class AddTodoScreen extends StatefulWidget {
AddTodoScreen({Key? key}) : super(key: key);
#override
_AddTodoScreenState createState() => _AddTodoScreenState();
}
class _AddTodoScreenState extends State<AddTodoScreen> {
//void main() async {
// await Hive.openBox<Todo>(HiveBoxes.todo);
//}
final GlobalKey<FormState> _formKey = GlobalKey<FormState>();
late String title;
late String description;
validated() {
if (_formKey.currentState != null && _formKey.currentState!.validate()) {
_onFormSubmit();
print("Form Validated");
} else {
print("Form Not Validated");
return;
}
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
backgroundColor: Color.fromRGBO(31, 39, 76, 1.0),
title: Text('스케줄 추가'),
),
body: SafeArea(
child: Form(
key: _formKey,
child: Padding(
padding: EdgeInsets.all(8.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
TextFormField(
autofocus: true,
initialValue: '',
decoration: InputDecoration(
labelText: '스케줄'
),
onChanged: (value) {
setState(() {
title = value;
});
},
validator: (String? value) {
if (value == null || value.trim().length == 0) {
return "required";
}
return null;
},
),
TextFormField(
initialValue: '',
decoration: const InputDecoration(
labelText: '메모',
),
onChanged: (value) {
setState(() {
description = value;
});
},
validator: (String? value) {
if (value == null || value.trim().length == 0) {
return "required";
}
return null;
},
),
ElevatedButton(
style: ElevatedButton.styleFrom(
primary:Color.fromRGBO(31, 39, 76, 1.0),
),
onPressed: () {
validated();
},
child: Text('추가'),
)
],
),
),
),
),
);
}
void _onFormSubmit() {
Box<Todo> contactsBox = Hive.box<Todo>(HiveBoxes.todo);
contactsBox.add(Todo(title: title, description: description));
Navigator.of(context).pop();
}
}
ui_test.dart
import 'package:work_a/screens/add_todo_Screen.dart';
class MyApp extends StatefulWidget {
#override
_MyAppState createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
#override
Widget build(BuildContext context) {
return MaterialApp(
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: MyHomePage(title: 'Todo Hive Example'),
);
}
}
class MyHomePage extends StatefulWidget {
MyHomePage({Key? key, required this.title}) : super(key: key);
final String title;
#override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
backgroundColor: Color.fromRGBO(31, 39, 76, 1.0),
centerTitle: true,
title: Text(widget.title),
),
body: Container(
child: ListView.builder(
itemBuilder: (context, index) {
return Dismissible(
background: Container(color: Colors.red),
key: UniqueKey(),
onDismissed: (direction) {},
child: ListTile(
title: Text('Title'),
subtitle: Text('Description'),
onTap: () {}),
);
},
),
),
floatingActionButton: FloatingActionButton(
tooltip: 'Add todo',
child: Icon(Icons.add),
onPressed: () => Navigator.of(context).push(
MaterialPageRoute(
builder: (context) => AddTodoScreen(),
),
),
),
);
}
}
boxs.dart
class HiveBoxes {
static String todo = 'todo_box';
}
todo.dart
import 'package:hive/hive.dart';
part 'todo.g.dart';
#HiveType(typeId: 0)
class Todo extends HiveObject {
#HiveField(0)
String? id;
#HiveField(1)
String title;
#HiveField(2)
String description;
Todo({required this.title, required this.description});
}
and
todo.g.dart
I'm assuming that you are saving Todo objects in todo_box.
Change this:
Hive.openBox('todo_box')
and this:
Hive.openBox<dynamic>('todo_box')
to this:
Hive.openBox<Todo>('todo_box')

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

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 to cast objects to a list in flutter

My API returns data in this format below, how do I use the data returned from the API?
{
"result": {
"circles": [
{
"_id": "5f03b28e81518d0017f250bf",
"name": "reflex",
"description": "reflex is not bad at the same 6time and then ",
"moderators": [],
"__v": 0
},
{
"_id": "5f03b32881518d0017f250c0",
"name": "dej ivo IDF",
"description": "talk ugh to be honest with my friends ",
"moderators": [],
"__v": 0
},
]
}
}
You can copy paste run full code below
You can parse with payloadFromJson , you can see related Payload class definition in full code
and display with FutureBuilder
code snippet
Payload payloadFromJson(String str) => Payload.fromJson(json.decode(str));
...
FutureBuilder(
future: _future,
builder: (context, AsyncSnapshot<Payload> snapshot) {
switch (snapshot.connectionState) {
case ConnectionState.none:
return Text('none');
case ConnectionState.waiting:
return Center(child: CircularProgressIndicator());
case ConnectionState.active:
return Text('');
case ConnectionState.done:
if (snapshot.hasError) {
return Text(
'${snapshot.error}',
style: TextStyle(color: Colors.red),
);
} else {
return ListView.builder(
itemCount: snapshot.data.result.circles.length,
working demo
full code
import 'package:flutter/material.dart';
import 'package:http/http.dart' as http;
import 'dart:convert';
Payload payloadFromJson(String str) => Payload.fromJson(json.decode(str));
String payloadToJson(Payload data) => json.encode(data.toJson());
class Payload {
Payload({
this.result,
});
Result result;
factory Payload.fromJson(Map<String, dynamic> json) => Payload(
result: Result.fromJson(json["result"]),
);
Map<String, dynamic> toJson() => {
"result": result.toJson(),
};
}
class Result {
Result({
this.circles,
});
List<Circle> circles;
factory Result.fromJson(Map<String, dynamic> json) => Result(
circles:
List<Circle>.from(json["circles"].map((x) => Circle.fromJson(x))),
);
Map<String, dynamic> toJson() => {
"circles": List<dynamic>.from(circles.map((x) => x.toJson())),
};
}
class Circle {
Circle({
this.id,
this.name,
this.description,
this.moderators,
this.v,
});
String id;
String name;
String description;
List<dynamic> moderators;
int v;
factory Circle.fromJson(Map<String, dynamic> json) => Circle(
id: json["_id"],
name: json["name"],
description: json["description"],
moderators: List<dynamic>.from(json["moderators"].map((x) => x)),
v: json["__v"],
);
Map<String, dynamic> toJson() => {
"_id": id,
"name": name,
"description": description,
"moderators": List<dynamic>.from(moderators.map((x) => x)),
"__v": v,
};
}
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
visualDensity: VisualDensity.adaptivePlatformDensity,
),
home: MyHomePage(title: 'Flutter Demo Home Page'),
);
}
}
class MyHomePage extends StatefulWidget {
MyHomePage({Key key, this.title}) : super(key: key);
final String title;
#override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
int _counter = 0;
Future<Payload> _future;
Future<Payload> _getRecords() async {
String jsonString = '''
{
"result": {
"circles": [
{
"_id": "5f03b28e81518d0017f250bf",
"name": "reflex",
"description": "reflex is not bad at the same 6time and then ",
"moderators": [],
"__v": 0
},
{
"_id": "5f03b32881518d0017f250c0",
"name": "dej ivo IDF",
"description": "talk ugh to be honest with my friends ",
"moderators": [],
"__v": 0
}
]
}
}
''';
var response = http.Response(jsonString, 200);
if (response.statusCode == 200) {
return payloadFromJson(jsonString);
} else {
print(response.statusCode);
}
}
#override
void initState() {
_future = _getRecords();
super.initState();
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: FutureBuilder(
future: _future,
builder: (context, AsyncSnapshot<Payload> snapshot) {
switch (snapshot.connectionState) {
case ConnectionState.none:
return Text('none');
case ConnectionState.waiting:
return Center(child: CircularProgressIndicator());
case ConnectionState.active:
return Text('');
case ConnectionState.done:
if (snapshot.hasError) {
return Text(
'${snapshot.error}',
style: TextStyle(color: Colors.red),
);
} else {
return ListView.builder(
itemCount: snapshot.data.result.circles.length,
itemBuilder: (context, index) {
return Card(
elevation: 6.0,
child: Padding(
padding: const EdgeInsets.only(
top: 6.0,
bottom: 6.0,
left: 8.0,
right: 8.0),
child: Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Text(snapshot
.data.result.circles[index].name),
Spacer(),
Text(snapshot.data.result.circles[index]
.description),
],
),
));
});
}
}
}));
}
}
Check the docs on JSON serialization.
Assuming that JSON is in a string format, this will convert it to a dart map:
Map<String, dynamic> data = jsonDecode(yourJsonString)

Flutter onChanged does not get called for any widget

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