Flutter 自定义底部表单

标签 flutter flutter-layout flutter-animation

我有一个 ListView,我想在其中实现一种使用带有操作的底部工作表删除列表项的好方法。最初,我只是在 onLongPress 事件处理程序中为我的列表项调用 showBottomSheet(),这将成功打开带有我的操作按钮的底部工作表。但是,这会自动向 AppBar 添加一个后退按钮,这不是我想要的。

然后我继续尝试动画,例如 SlideTransitionAnimatedPositioned:

class FoldersListWidget extends StatefulWidget {
  @override
  _FoldersListWidgetState createState() => _FoldersListWidgetState();
}

class _FoldersListWidgetState extends State<FoldersListWidget>
    with SingleTickerProviderStateMixin {
  double _bottomPosition = -70;

  @override
  Widget build(BuildContext context) {
    return Stack(
      children: [
        FutureBuilder<List<FolderModel>>(
          future: Provider.of<FoldersProvider>(context).getFolders(),
          builder: (context, snapshot) {
            if (!snapshot.hasData) {
              return Center(
                child: CircularProgressIndicator(),
              );
            }
            return ListView.builder(
              itemCount: snapshot.data.length,
              itemBuilder: (context, i) {
                final folder = snapshot.data[i];
                return Card(
                  shape: RoundedRectangleBorder(
                    borderRadius: BorderRadius.circular(15),
                  ),
                  margin: EdgeInsets.symmetric(vertical: 5, horizontal: 10),
                  elevation: 1,
                  child: ListTile(
                    title: Text(folder.folderName),
                    leading: Column(
                      mainAxisAlignment: MainAxisAlignment.center,
                      children: <Widget>[
                        Container(
                          width: 50,
                          child: Consumer<FoldersProvider>(
                            builder:
                                (BuildContext context, value, Widget child) {
                              return value.deleteFolderMode
                                  ? CircularCheckBox(
                                      value: false,
                                      onChanged: (value) {},
                                    )
                                  : Icon(
                                      Icons.folder,
                                      color: Theme.of(context).accentColor,
                                    );
                            },
                          ),
                        ),
                      ],
                    ),
                    subtitle: folder.numberOfLists != 1
                        ? Text('${folder.numberOfLists} items')
                        : Text('${folder.numberOfLists} item'),
                    onTap: () {},
                    onLongPress: () {
                      Provider.of<FoldersProvider>(context, listen: false)
                          .toggleDeleteFolderMode(true); // removes fab from screen
                      setState(() {
                        _bottomPosition = 0;
                      });
                    },
                  ),
                );
              },
            );
          },
        ),
        AnimatedPositioned(
          bottom: _bottomPosition,
          duration: Duration(milliseconds: 100),
          child: ClipRRect(
            borderRadius: BorderRadius.only(
              topLeft: Radius.circular(25),
              topRight: Radius.circular(25),
            ),
            child: Container(
              height: 70,
              width: MediaQuery.of(context).size.width,
              color: Theme.of(context).colorScheme.surface,
              child: Row(
                mainAxisAlignment: MainAxisAlignment.spaceAround,
                children: <Widget>[
                  Expanded(
                    child: IconAboveTextButton(
                      icon: Icon(Icons.cancel),
                      text: 'Cancel',
                      textColour: Colors.black,
                      opacity: 0.65,
                      onTap: () => setState(() {
                        _bottomPosition = -70;
                      }),
                    ),
                  ),
                  VerticalDivider(
                    color: Colors.black26,
                  ),
                  Expanded(
                    child: IconAboveTextButton(
                      icon: Icon(Icons.delete),
                      text: 'Delete',
                      textColour: Colors.black,
                      opacity: 0.65,
                    ),
                  ),
                ],
              ),
            ),
          ),
        ),
      ],
    );
  }
}

这会将底部的 Container 滑入和滑出屏幕,但我的问题是它覆盖了最后一个列表项:

任何人都可以提出一个更好的方法来做到这一点,或者只是一种调整 ListView 高度的方法,这样当 Container 向上滑动时,ListView 也向上滑动。

最佳答案

将 ListView.builder 包裹在一个容器中,并将其底部填充设置为 (70+16) 70(底部工作表的高度),16(一些默认的填充,如果你喜欢,可以让它看起来更好)。

return Container(
padding: EdgetInset.ony(bottom: (70+16)),
         child:ListView.builder(
              itemCount: snapshot.data.length,
              itemBuilder: (context, i) {
               .....
               .....

关于Flutter 自定义底部表单,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60149760/

相关文章:

flutter - flutter 中的自定义路由事务错误

google-chrome - 将离线模式添加到 Flutter Web 应用程序 - Service Workers/Pwas

flutter - CupertinoPageScaffold 的子小部件位于 CupertinoNavigationBar 后面

Flutter Web 鼠标区域小部件触发

Flutter - 如何按比例将 View 居中(以乘数偏移为中心)

flutter - 如何只在容器的特定一侧添加阴影?

flutter - 如何在 BLoC 模式上更改 Widget 时添加动画过渡?

flutter - 下面的构造函数在 dart 中如何工作,我已经提取了小部件,而 flutter 为我的小部件提供了下面的构造函数

flutter - Flutter:处理语音.OnError抖动语音

flutter - 如何从底部导航栏中删除图标?