我试着在列表视图上长按显示浮动按钮,但浮动按钮没有显示. 知道为什么吗?

我使用以下代码:

return GestureDetector(
          onLongPress: () {
            print('test');
            FloatingActionButton.extended(
              onPressed: () {
                print('test1');
              },
              icon: const Icon(Icons.add),
              label: const Text('Usuń'),
            );

更新1

我已经更新了帖子与更大的代码视图,以更好地了解构建过程… 我正在添加"Dodaj"按钮,到目前为止工作正常,并想添加另一个,"usuń"显示后,列表视图项长按. 你能看一下这段代码并指出我哪里做错了吗?

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      backgroundColor: Colors.grey[100],
      floatingActionButtonLocation: FloatingActionButtonLocation.centerFloat,
      floatingActionButton: FloatingActionButton.extended(
        onPressed: () {
          //addItem();
        },
        icon: const Icon(Icons.add),
        label: const Text('Dodaj'),
      ),
      appBar: AppBar(
        backgroundColor: Colors.grey[900],
        title: const Text('Lista zakupowa'),
        actions: [
          IconButton(
            onPressed: signUserOut,
            icon: const Icon(Icons.logout),
          )
        ],
      ),
      body: Center(
        child: FutureBuilder<List<PostListDetails>>(
          future: postsFuture,
          builder: (context, snapshot) {
            if (snapshot.connectionState == ConnectionState.waiting) {
              return const CircularProgressIndicator();
            } else if (snapshot.hasData) {
              return buildPosts(snapshot.data!);
            } else {
              return const Text("Brak danych...");
            }
          },
        ),
      ),
    );
  }


  // function to display fetched data on screen
  @override
  Widget buildPosts(List<PostListDetails> posts) {
    return ListView.builder(
      itemCount: posts.length,
      itemBuilder: (context, index) {
        final post = posts[index];
        int customCompare(PostListDetails a, PostListDetails b) {
          if (a.status != b.status) {
            return a.status!.toInt() - b.status!.toInt();
          }
          final int categoryCompare = a.kategoria.toString().compareTo(b.kategoria.toString());
          if (categoryCompare != 0) {
            return categoryCompare;
          }
          return a.nazwa.toString().compareTo(b.nazwa.toString());
        }
        return GestureDetector(
          onLongPress: () {
            print('test1');
            FloatingActionButton.extended(
              onPressed: () {
                print('test2');
              },
              icon: const Icon(Icons.add),
              label: const Text('Usuń'),
            );
          },
          child: Container(
            color: post.status! % 2 == 1 ? Colors.grey[100] : Colors.white,
            margin: const EdgeInsets.symmetric(vertical: 0.5, horizontal: 0),
            padding: const EdgeInsets.symmetric(vertical: 5, horizontal: 15),
            height: 50,
            width: double.maxFinite,
            child: Row(
              children: [
                Expanded(
                  flex: 8,
                    child: Column(
                    ...
                    ),
                  ),
                   Expanded(
                    flex: 2,
                    child: Column(
                    ...
                    ),
                  ),
            ],
            ),
            ),
            );
          },
        );
    }

更新2

我已经相应地修改了代码,但这次没有运气...长时间按下Listview项目后,OnLong Press按钮不显示. 这段代码应该创建一个Listview,其中包含一个项目列表和一个始终可见的浮动按钮"+Dodaj"(这部分工作得很好). 我也想创建一个项目后,长按一个"usuń"按钮…此部件不起作用,我的意思是按钮不可见.(未打印"测试1"和"测试2").

代码现在如下所示:

bool showButton = false;

@override
    Widget build(BuildContext context) {
    return Scaffold(
      backgroundColor: Colors.grey[100],
      floatingActionButtonLocation: FloatingActionButtonLocation.centerFloat,
      floatingActionButton: FloatingActionButton.extended(
        onPressed: () {
          //addList();
        },
        icon: const Icon(Icons.add),
        label: const Text('Dodaj'),
      ),
      appBar: AppBar(
        backgroundColor: Colors.grey[900],
        title: const Text('Lista zakupowa'),
        actions: [
          IconButton(
            onPressed: signUserOut,
            icon: const Icon(Icons.logout),
          )
        ],
      ),
      body: Center(
        child: FutureBuilder<List<PostListDetails>>(
          future: postsFuture,
          builder: (context, snapshot) {
            if (snapshot.connectionState == ConnectionState.waiting) {
              return const CircularProgressIndicator();
            } else if (snapshot.hasData) {
              return buildPosts(snapshot.data!);
            } else {
              return const Text("Brak danych...");
            }
          },
        ),
      ),
    );
  }


  // function to display fetched data on screen
  @override
  Widget buildPosts(List<PostListDetails> posts) {
    return ListView.builder(
      itemCount: posts.length,
      itemBuilder: (context, index) {
        final post = posts[index];
        int customCompare(PostListDetails a, PostListDetails b) {
          if (a.status != b.status) {
            return a.status!.toInt() - b.status!.toInt();
          }
          final int categoryCompare = a.kategoria.toString().compareTo(b.kategoria.toString());
          if (categoryCompare != 0) {
            return categoryCompare;
          }
          return a.nazwa.toString().compareTo(b.nazwa.toString());
        }
        GestureDetector(
          onLongPress: () {
            print('test1');
            setState(() => showButton = true);
          },
        );
        showButton ? FloatingActionButton.extended(
          onPressed: () {
            print('test2');
            //removeList();
          },
          icon: const Icon(Icons.add),
          label: const Text('Usuń'),
        ) : null;
        return Container(
          color: post.status! % 2 == 1 ? Colors.grey[100] : Colors.white,
          margin: const EdgeInsets.symmetric(vertical: 0.5, horizontal: 0),
          padding: const EdgeInsets.symmetric(vertical: 5, horizontal: 15),
          height: 50,
          width: double.maxFinite,
          child: Row(
            children: [
              Expanded(
                flex: 8,
                child: Column(
                    crossAxisAlignment: CrossAxisAlignment.start,
                    children: [
                      Text(post.nazwa!, textAlign: TextAlign.left, style: const TextStyle(fontWeight: FontWeight.bold,fontSize: 15,color: Colors.black)),
                      Text('${post.waga!.toString()} g.', textAlign: TextAlign.left, style: const TextStyle(fontWeight: FontWeight.normal,fontSize: 15,color: Colors.grey))
                    ]
                    ),
                  ),
                   Expanded(
                    flex: 2,
                    child: Column(
                        crossAxisAlignment: CrossAxisAlignment.start,
                        children: [
                          const Expanded(
                            flex: 0,
                            child: Row(
                            ),
                          ),
                          Expanded(
                            flex: 10,
                            child: Row(
                              children: [
                                CatIcon(imagePath: (Cat2Ico(post.kategoria!.toString()))),
                                Checkbox(
                                  value: Int2Bool(post.status!.toInt()),
                                  onChanged: (value) {
                                    setState(() {post.status = Bool2Int(value!);});
                                    saveStatus(post.nazwa!, post.status!, index);
                                    posts.sort(customCompare);
                                  },
                                ),
                              ]
                            ),
                          )
                      ]
                    ),
                  ),
            ],
            ),
          );
      },
    );
  } 

推荐答案

据我所知,在您的代码中有两个FloatingActionButton(Fab)小部件:一个应该始终可见,另一个应该只有在长时间按下ListView项后才可见,以实现以下目的:

  1. 您使用了一个名为showButton的布尔变量,该变量被初始化为False.此变量确定是否应显示附加FAB.在您的代码中,您使用if语句有条件地呈现FAB(我们将使用Column,三元运算符将不起作用):
if(showButton)
FloatingActionButton.extended(...)
  1. 在Scaffold的floatingActionButton属性的上下文中,将两个FAB包装在一列中以垂直排列它们:
Scaffold(
   floatingActionButton: Column(
      children: [
         FloatingActionButton.extended(...), // // The FAB that should always be visible
         if(showButton)
         FloatingActionButton.extended(...)// The FAB that will be visible after a long press
]),);
  1. 在Long Press事件处理程序中,使用setState来更新屏幕并将showButton的值设置为TRUE:
GestureDetector(
   onLongPress: () {
      setState(() => showButton = true);
},),

总而言之,它是如何应用于您提供的代码的:

bool showButton = false;

@override
Widget build(BuildContext context) {
  return Scaffold(
    backgroundColor: Colors.grey[100],
    floatingActionButtonLocation: FloatingActionButtonLocation.centerFloat,
    floatingActionButton: Column(
      children: [
        FloatingActionButton.extended(
          onPressed: () {
            // addList();
          },
          icon: const Icon(Icons.add),
          label: const Text('Dodaj'),
        ),
        if (showButton)
          FloatingActionButton.extended(
            onPressed: () {
              print('test2');
              // removeList();
            },
            icon: const Icon(Icons.add),
            label: const Text('Usuń'),
          ),
      ],
    ),
    appBar: AppBar(
      backgroundColor: Colors.grey[900],
      title: const Text('Lista zakupowa'),
      actions: [
        IconButton(
          onPressed: signUserOut,
          icon: const Icon(Icons.logout),
        ),
      ],
    ),
    body: Center(
      child: FutureBuilder<List<PostListDetails>>(
        future: postsFuture,
        builder: (context, snapshot) {
          if (snapshot.connectionState == ConnectionState.waiting) {
            return const CircularProgressIndicator();
          } else if (snapshot.hasData) {
            return buildPosts(snapshot.data!);
          } else {
            return const Text("Brak danych...");
          }
        },
      ),
    ),
  );
}

@override
Widget buildPosts(List<PostListDetails> posts) {
  return ListView.builder(
    itemCount: posts.length,
    itemBuilder: (context, index) {
      final post = posts[index];

      int customCompare(PostListDetails a, PostListDetails b) {
        if (a.status != b.status) {
          return a.status!.toInt() - b.status!.toInt();
        }
        final int categoryCompare = a.kategoria.toString().compareTo(b.kategoria.toString());
        if (categoryCompare != 0) {
          return categoryCompare;
        }
        return a.nazwa.toString().compareTo(b.nazwa.toString());
      }

      return GestureDetector(
        onLongPress: () {
          print('test1');
          setState(() => showButton = true);
        },
        child: Container(
          color: post.status! % 2 == 1 ? Colors.grey[100] : Colors.white,
          margin: const EdgeInsets.symmetric(vertical: 0.5, horizontal: 0),
          padding: const EdgeInsets.symmetric(vertical: 5, horizontal: 15),
          height: 50,
          width: double.maxFinite,
          child: Row(
            children: [
              Expanded(
                flex: 8,
                child: Column(
                  crossAxisAlignment: CrossAxisAlignment.start,
                  children: [
                    Text(
                      post.nazwa!,
                      textAlign: TextAlign.left,
                      style: const TextStyle(fontWeight: FontWeight.bold, fontSize: 15, color: Colors.black),
                    ),
                    Text(
                      '${post.waga!.toString()} g.',
                      textAlign: TextAlign.left,
                      style: const TextStyle(fontWeight: FontWeight.normal, fontSize: 15, color: Colors.grey),
                    ),
                  ],
                ),
              ),
              Expanded(
                flex: 2,
                child: Column(
                  crossAxisAlignment: CrossAxisAlignment.start,
                  children: [
                    const Expanded(
                      flex: 0,
                      child: Row(),
                    ),
                    Expanded(
                      flex: 10,
                      child: Row(
                        children: [
                          CatIcon(imagePath: (Cat2Ico(post.kategoria!.toString()))),
                          Checkbox(
                            value: Int2Bool(post.status!.toInt()),
                            onChanged: (value) {
                              setState(() {
                                post.status = Bool2Int(value!);
                              });
                              saveStatus(post.nazwa!, post.status!, index);
                              posts.sort(customCompare);
                            },
                          ),
                        ],
                      ),
                    ),
                  ],
                ),
              ),
            ],
          ),
        ),
      );
    },
  );
}

注意:正如在另一个答案中提到的,为了显示小部件,它必须是小部件树的一部分.在本例中,我将GestureDetector包装在ListView项的Container周围.

希望能有所帮助

Flutter相关问答推荐

如何使一个悬浮的appbar在flutter?

Flutter -如何将导航轨道标签靠左对齐?

如何使用flutter_local_notification包处理通知操作?

如何让经过Firebase身份验证的用户能够将Zip文件上载到Firebase云存储?

顶部对齐ListTile的[前导、标题、尾随]小部件

Flutter 附近的连接

使用 Firebase Realtime 实现高效流式传输

如何在Flutter 中使用选定的键和值从 map 列表创建 map

Flutter:我应该使用哪种应用内购买服务?

如何动态获取任何小部件的像素?

Flutter - firebase_auth_web 5.4.0 依赖于 intl ^0.17.0 但我必须使用更高版本 (intl ^0.18.0)

无状态小部件被奇怪地重建

无法使用 bloc 更新 ListView.builder 的特定时间

Flutter/Dart - 从外部类更新状态

如何在 flutter 中制作这种类型的扩展瓦片

将一个 Flutter 应用程序集成到另一个 Flutter 应用程序中

如何在 tabBar 中的选项卡之间制作垂直线?

Positioned 的宽度或 SizedBox 的宽度都不适用于堆栈小部件 - Flutter

解密 Modulr 安全令牌

如何将所有行项目平等地放在一行中?Flutter