首页 > 解决方案 > 如何使用 Flutter 创建 YouTube 模态底页?

问题描述

我想要一个模态底部表,我可以正常滚动而不关闭模态底部表。然后,当我位于列表顶部时,我希望能够使用滚动手势关闭模态底部工作表。

我想将视频中显示的 YouTube 样式模式底部表添加到我的应用程序中,但不幸的是我不知道该怎么做。

这是显示我的意思的视频链接:https ://drive.google.com/file/d/1977Ptq4Sox6WKGQkiTbCH_zydn8Mu05o/view?usp=sharing

这是在我的个人资料屏幕内:

@override
Widget build(BuildContext context) {
 return Material(
  color: Colors.transparent,
  child: Container(
    height: MediaQuery.of(context).size.height * 0.95,
    margin: EdgeInsets.only(bottom: 5, left: 10, right: 10),
    decoration: BoxDecoration(
      border: Border.all(color: Colors.black, width: 1.5),
      borderRadius: BorderRadius.circular(25),
      color: Colors.white,
    ),
    child: ClipRRect(
      borderRadius: BorderRadius.circular(23),
      child: DraggableScrollableSheet(
        initialChildSize: 1,
        minChildSize: 0.5,
        maxChildSize: 1,
        expand: false,
        builder: (BuildContext context, ScrollController _scrollController) {
          return SingleChildScrollView(
            controller: _scrollController,
            child: Column(
              children: [
                Container(
                  height: 590,
                  decoration: BoxDecoration(
                    border: Border(
                      bottom: BorderSide(width: 1.5, color: 
                      Colors.black),
                    ),
                    color: Colors.white,
                  ),
                  child: Stack(
                    children: [
                      InteractiveViewer(
                        transformationController:
                            _zoomProfilePictureController,
                        minScale: 1,
                        maxScale: 3,
                        onInteractionEnd: (ScaleEndDetails endDetails) {
                          setState(() {
                            _zoomProfilePictureController.value =
                                Matrix4.identity();
                          });
                        },
                        child: Swiper(
                          physics: NeverScrollableScrollPhysics(),
                          itemBuilder:
                              (BuildContext context, int imageIndex) {
                            return Hero(
                              tag: "Profile",
                              child: CachedNetworkImage(
                                imageUrl: widget.user.imageUrl[imageIndex],
                                fit: BoxFit.cover,
                                useOldImageOnUrlChange: true,
                                placeholder: (context, url) => Center(
                                  child: CircularProgressIndicator(
                                    strokeWidth: 3,
                                    valueColor: AlwaysStoppedAnimation<Color>(
                                      primaryColor.withOpacity(0.7),
                                    ),
                                  ),
                                ),
                                errorWidget: (context, url, error) => Icon(
                                  Icons.error_outline,
                                  size: 30,
                                  color: Colors.red,
                                ),
                              ),
                            );
                          },
                          itemCount: widget.user.imageUrl.length,
                          pagination: SwiperPagination(
                            alignment: Alignment.topCenter,
                            margin: EdgeInsets.all(0),
                            builder: DotSwiperPaginationBuilder(
                              color: Colors.white.withOpacity(0.7),
                              size: 8,
                              activeColor: widget.user.imageUrl.length > 1
                                  ? primaryColor
                                  : Colors.transparent,
                              activeSize: 10,
                            ),
                          ),
                          control: widget.user.imageUrl.length > 1
                              ? SwiperControl(
                                  padding: const EdgeInsets.only(top: 250),
                                  color: Colors.transparent,
                                  disableColor: Colors.transparent,
                                  size: 228,
                                )
                              : null,
                          loop: false,
                        ),
                      ),

这就是我调用 BottomSheet 的方式:

                        ListTile(
                        onTap: () => showModalBottomSheet(
                          backgroundColor: Colors.transparent,
                          context: context,
                          builder: (context) {
                            return ProfileInformationHomeScreen(
                              secondUser,
                              widget.currentUser,
                            );
                          },
                        ),

标签: flutter

解决方案


它是DraggableScrollableSheet

为 bottomSheet 创建一个小部件。

  @override
  Widget build(BuildContext context) {

    return ClipRRect(
      borderRadius: BorderRadius.only(
        topLeft: Radius.circular(12),
        topRight: Radius.circular(12),
      ),
      child: DraggableScrollableSheet(
        ///* it will be always visible 95% of screen,
        ///* if we drag down at 50% it will close the sheet
        initialChildSize: 0.95,
        minChildSize: 0.5,
        maxChildSize: .95,
        expand: false,

        builder: (BuildContext context, c) {
          return Container(
            color: Colors.white,
            child: ListView(
              controller: c,
              children: [
              /// your widgets

调用一个方法showModalBottomSheet

 _showBottomSheet(BuildContext context) {
      showModalBottomSheet(
        context: context,
        isScrollControlled: true,
        backgroundColor: Colors.transparent,
        builder: (context) => DestinationBottomSheetWidget(),
      );
    }

要关闭 buttonSheet,您可以拖动或使用 DraggableScrollableSheetbuilder 内的按钮并使用Navigator.of(context).pop().

我喜欢这个并添加项目ListView

  /// heading
                Padding(
                  padding: EdgeInsets.only(
                    left: 20,
                    
                  ),
                  child: Row(
                    mainAxisAlignment: MainAxisAlignment.spaceBetween,
                    children: [
                      GestureDetector(
                        onTap: () => Navigator.of(context).pop(),
                        child: Icon(
                          Icons.close,
                          color: Colors.grey,
                        ),
                      ),
                      Text(
                        "Title",
                        textAlign: TextAlign.center,
                       
                      ),

                      ///* this empty widget will handle the spaces
                      Icon(
                        Icons.close,
                        color: Colors.grey.withOpacity(0.0),
                      ),
                    ],
                  ),
                ),

更多颤振文档 youtube


推荐阅读