flutter 为什么不显示浮动按钮

deyfvvtc  于 2023-10-22  发布在  Flutter
关注(0)|答案(3)|浏览(124)

我尝试在列表视图上显示浮动按钮长按,但浮动按钮不显示。知道为什么吗?
我使用以下代码:

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

Update 1
我已经更新了更大的代码视图,以便更好地理解构建过程...我正在添加“Dodaj”按钮,到目前为止工作正常,并希望添加另一个,“Dodaj”列表视图项目长按后显示。你能看看这段代码,告诉我我做错了什么吗?

@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
我已经相应地修改了代码,但这次没有运气... onlongpress按钮不显示后长按列表视图项目.这段代码应该创建一个列表视图,其中包含一个项目列表和一个始终可见的浮动按钮“+ Dodaj”(这部分工作正常)。我也想创建一个项目长按后的”按钮.这部分不工作,我的意思是按钮是不可见的。(“测试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);
                                  },
                                ),
                              ]
                            ),
                          )
                      ]
                    ),
                  ),
            ],
            ),
          );
      },
    );
  }
vlju58qv

vlju58qv1#

@幻觉是对的:为了显示按钮,它需要在Widget树中。
下面是一个工作的Flutter应用程序的例子,它显示了长按按钮:

import 'package:flutter/material.dart';

void main() => runApp(const MyApp());

class MyApp extends StatelessWidget {
  const MyApp({super.key});
  @override
  Widget build(BuildContext context) => const MaterialApp(home: MyHomePage());
}

class MyHomePage extends StatefulWidget {
  const MyHomePage({super.key});
  @override
  State<MyHomePage> createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  bool showButton = false;

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: GestureDetector(
        onLongPress: () {
          setState(() => showButton = true);
        },
      ),
      floatingActionButton: showButton
          ? FloatingActionButton.extended(
              onPressed: () {},
              icon: const Icon(Icons.add),
              label: const Text('Usuń'),
            )
          : null,
    );
  }
}
s6fujrry

s6fujrry2#

据我所知,在你的代码中,你有两个浮动按钮(FAB)小部件:一个应该始终可见,另一个应该只在长按ListView项目后可见,以实现这一点:
1.我们使用了一个名为showButton的布尔变量,它被初始化为false。该变量确定是否应显示附加FAB。在代码中,使用if语句有条件地呈现FAB(我们将使用列,三元运算符不起作用):

if(showButton)
FloatingActionButton.extended(...)

1.在Scaffold的floatingActionButton属性的上下文中,您将两个FAB Package 在一个列中以垂直排列它们:

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.在长按事件处理程序中,使用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 Package 在ListView项的Container周围。
希望它能帮助

svmlkihl

svmlkihl3#

我从FloatingActionButton documentation复制了示例代码并修改了一点以允许显示/隐藏FAB,这应该会给你一些给予想法。关键点是将FloatingActionButton放在ScaffoldfloatingActionButton字段中,并使用一些逻辑(我在这里使用基本的setState)来显示/隐藏基于bool的FAB。

import 'package:flutter/material.dart';


void main() {
  runApp(const FloatingActionButtonExampleApp());
}

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

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      theme: ThemeData(useMaterial3: true),
      home: const FloatingActionButtonExample(),
    );
  }
}

class FloatingActionButtonExample extends StatefulWidget {
  const FloatingActionButtonExample({super.key});

  @override
  State<FloatingActionButtonExample> createState() =>
      _FloatingActionButtonExampleState();
}

class _FloatingActionButtonExampleState
    extends State<FloatingActionButtonExample> {
  // The FAB's foregroundColor, backgroundColor, and shape
  static const List<(Color?, Color? background, ShapeBorder?)> customizations =
      <(Color?, Color?, ShapeBorder?)>[
    (null, null, null),parameters.
    (null, Colors.green, null),
    (Colors.white, Colors.green, null),
    (Colors.white, Colors.green, CircleBorder()),
  ];
  int index = 0;
  bool showFab = false; // <-- to control FAB state shown/hidden

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('FloatingActionButton Sample'),
      ),
      body: Center(
          child: GestureDetector(
              onTap: () {
                // to change the state
                setState(() {
                  showFab = !showFab;
                });
              },
              child: const Text('Press this to show/hide FAB'))),
      // use the FAB like this
      floatingActionButton: showFab
          ? FloatingActionButton(
              onPressed: () {
                setState(() {
                  index = (index + 1) % customizations.length;
                });
              },
              foregroundColor: customizations[index].$1,
              backgroundColor: customizations[index].$2,
              shape: customizations[index].$3,
              child: const Icon(Icons.navigation),
            )
          : null,
    );
  }
}

相关问题