无法在 Listview Flutter 中更新新数据
Unable to update new data in Listview Flutter
大家好,我是 Flutter 的新手,我一直在尝试构建一个模拟应用程序来显示提要,它使用模拟数据可以正常工作,但是当我尝试添加新的输入数据时,它会被添加但不会得到更新,请帮助我,我完全理解我的错误可能是非常微不足道和愚蠢的,但我已经被困了好几个星期了,这是代码。
这是显示一切的画面
import 'package:deep_pocket/models/data_feed.dart';
import 'package:deep_pocket/models/mock_data.dart';
import 'package:deep_pocket/widgets/menu_buttons.dart';
import 'package:deep_pocket/widgets/post_widget.dart';
import 'package:deep_pocket/screens/user_input.dart';
import 'package:flutter/material.dart';
import 'package:flutter/cupertino.dart';
import 'package:provider/provider.dart';
class feedScreen extends StatefulWidget {
@override
State<feedScreen> createState() => _feedScreenState();
}
class _feedScreenState extends State<feedScreen> {
int filter = 0;
void updateFilter(tx, context) {
setState(() {
filter = tx;
});
Navigator.of(context).pop();
}
void filterSheet(ctx) {
showModalBottomSheet(
context: ctx,
builder: (ctx) => Container(
height: 300,
child: SingleChildScrollView(
child: Container(
height: 280,
child: ListView.builder(
itemCount: Tag.length,
itemBuilder: (ctx, i) => TextButton(
onPressed: () {
return updateFilter(i, context);
},
child: Text(Tag[i]),
)),
)),
));
}
@override
Widget build(BuildContext context) {
var posts = Provider.of<mockData>(context).items;
print(posts.length);
if (filter != 0) {
posts = posts.where((i) => i.tag == filter).toList();
}
return Scaffold(
// drawer: Drawer(
// // Populate the Drawer in the next step.
// ),
appBar: AppBar(
title: const Text("Home"),
actions: [
TextButton(
onPressed: () => {filterSheet(context)},
child: const Text(
"Filters",
style: TextStyle(color: Colors.white),
))
],
),
body: SingleChildScrollView(
child: Column(
children: [
menuButtons(),
Container(
padding: const EdgeInsets.all(8),
child: ListView.builder(
shrinkWrap: true,
physics: NeverScrollableScrollPhysics(),
itemCount: posts.length,
itemBuilder: (ctx, i) => postWidget(post: posts[i])),
),
],
),
),
floatingActionButton: FloatingActionButton(
onPressed: () {
Navigator.pushNamed(context, userInput.route);
},
child: const Icon(Icons.add)),
);
}
}
这是我处理输入的地方
import 'package:deep_pocket/models/data_feed.dart';
import 'package:deep_pocket/models/mock_data.dart';
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
class userInput extends StatefulWidget {
static const route = '/user-input';
@override
_userInputState createState() => _userInputState();
}
class _userInputState extends State<userInput> {
var _chosenValue = 'all';
final titleController = TextEditingController();
final bodyController = TextEditingController();
void submitted() {
String titleCheck = titleController.text;
String bodyCheck = bodyController.text;
int tag = Tag.indexOf(_chosenValue);
if (titleCheck.isEmpty || bodyCheck.length < 10) {
return;
}
final newPost = dataFeed(
imgsrc: "https://i.pravatar.cc/150?u=a042581f4e29026704d",
name: "Priyam ",
title: titleCheck,
text: bodyCheck,
tag: tag,
);
titleController.dispose();
bodyController.dispose();
Provider.of<mockData>(context, listen: false).addPost(newPost);
Navigator.of(context).pop();
}
@override
Widget build(BuildContext context) {
return Scaffold(
floatingActionButton: FloatingActionButton.extended(
onPressed: submitted,
label: const Text("SUBMIT"),
),
appBar: AppBar(
title: Text("New Post"),
),
body: Container(
child: Column(
children: [
TextField(
controller: titleController,
decoration: const InputDecoration(
label: Text("Title"),
enabledBorder: OutlineInputBorder(),
),
),
TextField(
controller: bodyController,
decoration: const InputDecoration(
label: Text("Body"),
enabledBorder: OutlineInputBorder(),
),
),
DropdownButton<String>(
focusColor: Colors.white,
value: _chosenValue,
//elevation: 5,
style: TextStyle(color: Colors.white),
iconEnabledColor: Colors.black,
items: Tag.map<DropdownMenuItem<String>>((String value) {
return DropdownMenuItem<String>(
value: value,
child: Text(
value,
style: TextStyle(color: Colors.black),
),
);
}).toList(),
hint: const Text(
"select a tag",
style: TextStyle(
color: Colors.black,
fontSize: 14,
fontWeight: FontWeight.w500),
),
onChanged: (String? value) {
setState(() {
_chosenValue = value.toString();
});
},
),
],
),
),
);
}
}
这是模拟数据class
import 'package:deep_pocket/models/data_feed.dart';
import 'package:flutter/material.dart';
class mockData with ChangeNotifier {
final List<dataFeed> _data = [
dataFeed(
imgsrc: "https://i.pravatar.cc/150?u=a042581f4e29026704d",
name: "Priyam Srivastava",
title: "How to change room ?",
tag: 1,
text:
"I would like to know the process of changing my room cause I have not been able to study, and my roomate always plays music and drinks too much then shouts all night, please tell me how",
),
dataFeed(
imgsrc: "https://i.pravatar.cc/150?u=a042581f4e29026704d",
title: "Anyone intresed in playing BGMI?",
name: "Part Agarwal",
tag: 2,
text:
"So I have been looing for a squad for a long time and now i have finally decided that I am gonna buckle up and ask you all to join me",
),
dataFeed(
imgsrc: "https://i.pravatar.cc/150?u=a042581f4e29026704d",
title: "How to solve this question in O(n) complexity",
name: "Preet Singh",
tag: 3,
text:
"So I have been looing for a squad for a long time and now i have finally decided that I am gonna buckle up and ask you all to join me",
),
];
List<dataFeed> get items {
return [..._data];
}
void addPost(dataFeed newpost) {
final newPost = dataFeed(
imgsrc: newpost.imgsrc,
name: newpost.name,
title: newpost.title,
text: newpost.text,
tag: newpost.tag,
);
_data.insert(0, newPost);
print(_data.length);
notifyListeners();
}
}
数据字段class
import 'package:provider/provider.dart';
import 'package:flutter/material.dart';
List<String> Tag = [
'all',
'Query',
'Games',
'Doubt',
'Selling',
'CabShare',
'Announcement',
'OpenDiscussion',
];
class dataFeed with ChangeNotifier {
final String id = DateTime.now().toString();
final String name;
final String title;
final String text;
final String imgsrc;
final DateTime date = DateTime.now();
final int tag;
dataFeed({
required this.imgsrc,
required this.name,
required this.title,
this.tag = 0,
required this.text,
});
首先,用 ChangeNotifierProvider<T>
包装 Scaffold 并像这样更改浮动操作按钮 onPressed
函数:
ChangeNotifierProvider<mockData>(
create: (context) => mockData(),
builder: (context, child){
var posts = context.select((mockData m) => m.items);
return Scaffold(
body: SingleChildScrollView(
....
),
floatingActionButton: FloatingActionButton(
onPressed: () async {
//Waiting for result
var newData = await Navigator.pushNamed(context, userInput.route);
if(newData != null){
context.read<mockData>().addPost(newData);
}
},
child: const Icon(Icons.add)),
);
}
);
其次,像这样更改 userInput
class 中的 submitted
函数:
void submitted(){
///....
final newPost = dataFeed(
imgsrc: "https://i.pravatar.cc/150?u=a042581f4e29026704d",
name: "Priyam ",
title: titleCheck,
text: bodyCheck,
tag: tag,
);
titleController.dispose();
bodyController.dispose();
//Sending newPost to previous page via Navigator.
Navigator.of(context).pop(newPost); //<- Attention
}
并更改 _feedScreenState
中的以下行以收听列表。
相反
var posts = Provider.of<mockData>(context).items;
这个:
var posts = context.watch<mockData>().items;
//or
var posts = context.select((mockData m) => m.items);
或添加一个 Selector
收听列表的小部件
Selector<mockData, List<dataFeed>>(
selector: (_, m) => m.items,
builder: (_, items, __) => ListView.builder(
//...
itemBuilder: (ctx, i) => postWidget(post: items[i])),
)
)
大家好,我是 Flutter 的新手,我一直在尝试构建一个模拟应用程序来显示提要,它使用模拟数据可以正常工作,但是当我尝试添加新的输入数据时,它会被添加但不会得到更新,请帮助我,我完全理解我的错误可能是非常微不足道和愚蠢的,但我已经被困了好几个星期了,这是代码。 这是显示一切的画面
import 'package:deep_pocket/models/data_feed.dart';
import 'package:deep_pocket/models/mock_data.dart';
import 'package:deep_pocket/widgets/menu_buttons.dart';
import 'package:deep_pocket/widgets/post_widget.dart';
import 'package:deep_pocket/screens/user_input.dart';
import 'package:flutter/material.dart';
import 'package:flutter/cupertino.dart';
import 'package:provider/provider.dart';
class feedScreen extends StatefulWidget {
@override
State<feedScreen> createState() => _feedScreenState();
}
class _feedScreenState extends State<feedScreen> {
int filter = 0;
void updateFilter(tx, context) {
setState(() {
filter = tx;
});
Navigator.of(context).pop();
}
void filterSheet(ctx) {
showModalBottomSheet(
context: ctx,
builder: (ctx) => Container(
height: 300,
child: SingleChildScrollView(
child: Container(
height: 280,
child: ListView.builder(
itemCount: Tag.length,
itemBuilder: (ctx, i) => TextButton(
onPressed: () {
return updateFilter(i, context);
},
child: Text(Tag[i]),
)),
)),
));
}
@override
Widget build(BuildContext context) {
var posts = Provider.of<mockData>(context).items;
print(posts.length);
if (filter != 0) {
posts = posts.where((i) => i.tag == filter).toList();
}
return Scaffold(
// drawer: Drawer(
// // Populate the Drawer in the next step.
// ),
appBar: AppBar(
title: const Text("Home"),
actions: [
TextButton(
onPressed: () => {filterSheet(context)},
child: const Text(
"Filters",
style: TextStyle(color: Colors.white),
))
],
),
body: SingleChildScrollView(
child: Column(
children: [
menuButtons(),
Container(
padding: const EdgeInsets.all(8),
child: ListView.builder(
shrinkWrap: true,
physics: NeverScrollableScrollPhysics(),
itemCount: posts.length,
itemBuilder: (ctx, i) => postWidget(post: posts[i])),
),
],
),
),
floatingActionButton: FloatingActionButton(
onPressed: () {
Navigator.pushNamed(context, userInput.route);
},
child: const Icon(Icons.add)),
);
}
}
这是我处理输入的地方
import 'package:deep_pocket/models/data_feed.dart';
import 'package:deep_pocket/models/mock_data.dart';
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
class userInput extends StatefulWidget {
static const route = '/user-input';
@override
_userInputState createState() => _userInputState();
}
class _userInputState extends State<userInput> {
var _chosenValue = 'all';
final titleController = TextEditingController();
final bodyController = TextEditingController();
void submitted() {
String titleCheck = titleController.text;
String bodyCheck = bodyController.text;
int tag = Tag.indexOf(_chosenValue);
if (titleCheck.isEmpty || bodyCheck.length < 10) {
return;
}
final newPost = dataFeed(
imgsrc: "https://i.pravatar.cc/150?u=a042581f4e29026704d",
name: "Priyam ",
title: titleCheck,
text: bodyCheck,
tag: tag,
);
titleController.dispose();
bodyController.dispose();
Provider.of<mockData>(context, listen: false).addPost(newPost);
Navigator.of(context).pop();
}
@override
Widget build(BuildContext context) {
return Scaffold(
floatingActionButton: FloatingActionButton.extended(
onPressed: submitted,
label: const Text("SUBMIT"),
),
appBar: AppBar(
title: Text("New Post"),
),
body: Container(
child: Column(
children: [
TextField(
controller: titleController,
decoration: const InputDecoration(
label: Text("Title"),
enabledBorder: OutlineInputBorder(),
),
),
TextField(
controller: bodyController,
decoration: const InputDecoration(
label: Text("Body"),
enabledBorder: OutlineInputBorder(),
),
),
DropdownButton<String>(
focusColor: Colors.white,
value: _chosenValue,
//elevation: 5,
style: TextStyle(color: Colors.white),
iconEnabledColor: Colors.black,
items: Tag.map<DropdownMenuItem<String>>((String value) {
return DropdownMenuItem<String>(
value: value,
child: Text(
value,
style: TextStyle(color: Colors.black),
),
);
}).toList(),
hint: const Text(
"select a tag",
style: TextStyle(
color: Colors.black,
fontSize: 14,
fontWeight: FontWeight.w500),
),
onChanged: (String? value) {
setState(() {
_chosenValue = value.toString();
});
},
),
],
),
),
);
}
}
这是模拟数据class
import 'package:deep_pocket/models/data_feed.dart';
import 'package:flutter/material.dart';
class mockData with ChangeNotifier {
final List<dataFeed> _data = [
dataFeed(
imgsrc: "https://i.pravatar.cc/150?u=a042581f4e29026704d",
name: "Priyam Srivastava",
title: "How to change room ?",
tag: 1,
text:
"I would like to know the process of changing my room cause I have not been able to study, and my roomate always plays music and drinks too much then shouts all night, please tell me how",
),
dataFeed(
imgsrc: "https://i.pravatar.cc/150?u=a042581f4e29026704d",
title: "Anyone intresed in playing BGMI?",
name: "Part Agarwal",
tag: 2,
text:
"So I have been looing for a squad for a long time and now i have finally decided that I am gonna buckle up and ask you all to join me",
),
dataFeed(
imgsrc: "https://i.pravatar.cc/150?u=a042581f4e29026704d",
title: "How to solve this question in O(n) complexity",
name: "Preet Singh",
tag: 3,
text:
"So I have been looing for a squad for a long time and now i have finally decided that I am gonna buckle up and ask you all to join me",
),
];
List<dataFeed> get items {
return [..._data];
}
void addPost(dataFeed newpost) {
final newPost = dataFeed(
imgsrc: newpost.imgsrc,
name: newpost.name,
title: newpost.title,
text: newpost.text,
tag: newpost.tag,
);
_data.insert(0, newPost);
print(_data.length);
notifyListeners();
}
}
数据字段class
import 'package:provider/provider.dart';
import 'package:flutter/material.dart';
List<String> Tag = [
'all',
'Query',
'Games',
'Doubt',
'Selling',
'CabShare',
'Announcement',
'OpenDiscussion',
];
class dataFeed with ChangeNotifier {
final String id = DateTime.now().toString();
final String name;
final String title;
final String text;
final String imgsrc;
final DateTime date = DateTime.now();
final int tag;
dataFeed({
required this.imgsrc,
required this.name,
required this.title,
this.tag = 0,
required this.text,
});
首先,用 ChangeNotifierProvider<T>
包装 Scaffold 并像这样更改浮动操作按钮 onPressed
函数:
ChangeNotifierProvider<mockData>(
create: (context) => mockData(),
builder: (context, child){
var posts = context.select((mockData m) => m.items);
return Scaffold(
body: SingleChildScrollView(
....
),
floatingActionButton: FloatingActionButton(
onPressed: () async {
//Waiting for result
var newData = await Navigator.pushNamed(context, userInput.route);
if(newData != null){
context.read<mockData>().addPost(newData);
}
},
child: const Icon(Icons.add)),
);
}
);
其次,像这样更改 userInput
class 中的 submitted
函数:
void submitted(){
///....
final newPost = dataFeed(
imgsrc: "https://i.pravatar.cc/150?u=a042581f4e29026704d",
name: "Priyam ",
title: titleCheck,
text: bodyCheck,
tag: tag,
);
titleController.dispose();
bodyController.dispose();
//Sending newPost to previous page via Navigator.
Navigator.of(context).pop(newPost); //<- Attention
}
并更改 _feedScreenState
中的以下行以收听列表。
相反
var posts = Provider.of<mockData>(context).items;
这个:
var posts = context.watch<mockData>().items;
//or
var posts = context.select((mockData m) => m.items);
或添加一个 Selector
收听列表的小部件
Selector<mockData, List<dataFeed>>(
selector: (_, m) => m.items,
builder: (_, items, __) => ListView.builder(
//...
itemBuilder: (ctx, i) => postWidget(post: items[i])),
)
)