У меня есть вопрос
здесь я получаю данные из API и создал вторую страницу, которую могу опубликовать из своего приложения в API.
когда я публикую что-то и возвращаюсь на главную страницу, где все сообщения из моего API освещены, мне нужно обновить... когда я обновляю его, новое сообщение будет добавлено, но обновляющий круг не будет хватит обновляться..
Я понятия не имею, что делать ..
В одном месте я прочитал, что это из-за заданного состояния, которое создает бесконечный цикл.. но в моем случае мне нужно заданное состояние для обновления пользовательского интерфейса.. пожалуйста, скажите мне, что делать. пожалуйста, помогите мне, спасибо.
это мой код:
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return const MaterialApp(
home: MyPage(),
);
}
}
class MyPage extends StatefulWidget {
const MyPage({super.key});
@override
State<MyPage> createState() => _MyPageState();
}
class _MyPageState extends State<MyPage> {
final RefreshController _myrefreshcontroller = RefreshController();
late List<Post>? listpost;
@override
void initState() {
fetchAllPosts().then((value) => listpost = value);
super.initState();
}
void _onRefresh() async {
await fetchAllPosts().then((value) {
setState(() {
listpost = value;
});
});
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('welcome welcome'),
),
body: Center(
child: FutureBuilder(
future: fetchAllPosts(),
builder: (context, snapshot) {
if (snapshot.hasData) {
return SmartRefresher(
controller: _myrefreshcontroller,
onRefresh: _onRefresh,
child: ListView.builder(
itemCount: listpost!.length,
itemBuilder: (context, index) {
return Card(
child: ListTile(
contentPadding: const EdgeInsets.all(20),
title: Padding(
padding: const EdgeInsets.all(20),
child: Text(listpost![index].id.toString())),
subtitle: Padding(
padding: const EdgeInsets.all(20),
child: Text(listpost![index].content.toString())),
),
);
},
),
);
} else if (snapshot.hasError) {
return Text("${snapshot.error}");
}
return const CircularProgressIndicator();
},
),
),
Возможно, это из-за SmartRefresher, я не знаю, почему вы не использовали обычный виджет RefreshIndicator. У меня это отлично работает, даже с setState()
Future<void> delay() async {
await Future.delayed(Duration(seconds: 4)).then((value) {
setState(() {});
});
}
...
child: RefreshIndicator(
onRefresh: delay,
child: child,
),
...
Проблема в том, что вы выполняете fetchAllPosts()
. Вам следует передать эту функцию в качестве параметра будущему методу FutureBuilder следующим образом:
future: fetchAllPosts
,
но что на самом деле принято и неправильно, так это следующее:
future: fetchAllPosts()
Пакет, который вы используете для обновления, рекомендует добавлять _refreshController.refreshCompleted()
при успешном обновлении, которого нет в вашем коде. После небольшой обработки ошибок это должно выглядеть так:
void _onRefresh() async {
fetchAllPosts().then((value) {
setState(() {
listPost = value;
});
_refreshController.refreshCompleted();
}).catchError((error) {
_refreshController.refreshFailed();
});
}
И да, хотя setState
вызвал бы бесконечный цикл, если бы вы использовали значение RefreshIndicator
Flutter по умолчанию, в случаях, когда вам нужно запустить перестройку в вашем FutureBuilder
без сброса будущего, вы можете обойти это, сначала сделав будущее запомненным.
Таким образом, запоминание вашего будущего изменит поведение вашего FutureBuilder
, чтобы оно восстанавливалось только тогда, когда само будущее меняется, а не при каждом setState
звонке.
Для этого, исходя из вашего кода, код перед вашим методом _onRefresh
теперь будет выглядеть так:
final RefreshController _refreshController = RefreshController();
late Future<List<Post>> futurePosts;
late List<Post>? listPost;
@override
void initState() {
super.initState();
futurePosts = fetchAllPosts();
}
и в своем FutureBuilder
вы обновите будущее, чтобы использовать запомненные данные, которые тогда будут выглядеть так:
FutureBuilder<List<Post>>(
future: futurePosts,
…
Какие ошибки вы получаете, если таковые имеются? Как выглядит ваша функция fetchAllPosts?