简体   繁体   English

如何在 Flutter 中将 ScaffoldMessenger 中的 Snackbar 显示为 Widget?

[英]How to Show Snackbar within ScaffoldMessenger as Widget in Flutter?

I have a new use case for Snackbar.我有一个 Snackbar 的新用例。 I was asked to make a program which reads articles from API and it will show Snackbar when it reaches the end of articles.我被要求制作一个程序来读取来自 API 的文章,当它到达文章末尾时会显示 Snackbar。 I meant, all examples of using Snackbar always use a button in order to display it.我的意思是,所有使用 Snackbar 的例子总是使用一个按钮来显示它。 How can I display Snackbar when I reach the end of articles?当我到达文章结尾时如何显示 Snackbar?

This is my code:这是我的代码:

    return ListView.builder(
      itemBuilder: (BuildContext context, int index) {
        if (state.hasReachedMax) {
          return const SnackbarPage(); //<= This one
        } else {
          if (index >= state.posts.length) {
            return const BottomLoader();
          } else {
            return PostListItem(post: state.posts[index]);
          }
        }
      },
      itemCount: state.hasReachedMax ? state.posts.length : state.posts.length + 1,
      controller: _scrollController,
    );
  • snackbar.dart小吃店.dart
    import 'package:flutter/material.dart';

    class SnackbarPage extends StatelessWidget {
      const SnackbarPage({super.key});

      @override
      Widget build(BuildContext context) {
        return Scaffold(
          body: ScaffoldMessenger(  //Error here
            child: SnackBar(
              content: const Text('Reach the end of posts'),
              action: SnackBarAction(
                onPressed: () {
                  //if action button is pressed
                },
                label: 'Close',
              ),
            ),
          ),
        );
      }
    }

I got error: Null check operator used on a null value我收到错误: Null check operator used on a null value

It seems that ScaffoldMessenger cannot be used as a Widget as return.好像ScaffoldMessenger不能作为Widget as return。

References: Snackbar ScaffoldMessenger参考资料: Snackbar ScaffoldMessenger

I think you can use the Scaffold.of method to access the Scaffold ancestor of your ListView.builder, and then call the showSnackBar method on the Scaffold to display the Snackbar.我想你可以使用 Scaffold.of 方法来访问你的 ListView.builder 的 Scaffold 祖先,然后调用 Scaffold 上的 showSnackBar 方法来显示 Snackbar。

Would something like this work?这样的事情行得通吗?

return ListView.builder(
  itemBuilder: (BuildContext context, int index) {
    if (state.hasReachedMax) {
      Scaffold.of(context).showSnackBar(
        SnackBar(
          content: const Text('Reach the end of posts'),
          action: SnackBarAction(
            onPressed: () {
              //if action button is pressed
            },
            label: 'Close',
          ),
        ),
      );
      return Container();
    } else {
      if (index >= state.posts.length) {
        return const BottomLoader();
      } else {
        return PostListItem(post: state.posts[index]);
      }
    }
  },
  itemCount: state.hasReachedMax ? state.posts.length : state.posts.length + 1,
  controller: _scrollController,
);
To display a Snackbar when you reach the end of articles, you can use the Scaffold. of(context).showSnackBar() method.

For Example:

// Import the Scaffold and SnackBar classes
import 'package: flutter/material.dart';

// ...

// Inside your build method
if (articles.length == 0) {
  // Display the SnackBar when there are no more articles to read
  Scaffold.of(context).showSnackBar(
    SnackBar(
      content: Text('No more articles to read'),
    ),
  );
}

This will display the Snackbar when the articles list is empty. You can customize the Snackbar by setting its content, duration, and other properties.

You can use ScaffoldMessanger to show snackbr as below,您可以使用 ScaffoldMessanger 来显示 snackbr,如下所示,

return ListView.builder(
  itemBuilder: (BuildContext context, int index) {
    if (state.hasReachedMax) {
     ScaffoldMessanger.of(context).showSnackBar( <--- here use ScaffoldMessanger instead of Scaffold
     SnackBar(
      content: const Text('Reach the end of posts'),
      action: SnackBarAction(
        onPressed: () {
          //if action button is pressed
        },
        label: 'Close',
      ),
    ),
  );
  return SizedBox();
   } else {
     if (index >= state.posts.length) {
       return const BottomLoader();
   } else {
    return PostListItem(post: state.posts[index]);
   }
 }
},
  itemCount: state.hasReachedMax ? state.posts.length : state.posts.length + 1,
  controller: _scrollController,
);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM