You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Flutter产品组件横向排列改纵向排列求助

解决Flutter产品组件横向改纵向排列问题

问题说明

当前产品组件(尤其是热门产品模块)是横向排列滚动的,需要改为纵向向下排列。组件尺寸已符合要求,作为Flutter新手尝试了ListView、Column等组件但未成功实现需求。

修改方案

你的代码里,热门产品(ProductType.POPULAR_PRODUCT) 模块用的是横向ListView,只需要调整几个关键参数就能改成纵向:

  • 把ListView.builder的scrollDirection从Axis.horizontal改为Axis.vertical
  • 移除外层固定高度的SizedBox,给ListView加上shrinkWrap: true让它自适应内容高度
  • 去掉每个item容器的固定width:195(如果需要让item占满宽度,可改为width: double.infinity)
  • 同步修改骨架屏(productList为null时)的对应配置

修改后的完整代码

return Consumer<ProductProvider>(
  builder: (context, prodProvider, child) {
    List<Product> productList;
    if (productType == ProductType.LATEST_PRODUCT) {
      productList = prodProvider.latestProductList;
    } else if (productType == ProductType.POPULAR_PRODUCT) {
      productList = prodProvider.popularProductList;
    }
    if (productList == null) {
      return productType == ProductType.POPULAR_PRODUCT
          ? ListView.builder(
              scrollDirection: Axis.vertical, // 改为纵向滚动
              shrinkWrap: true, // 自适应内容高度
              physics: BouncingScrollPhysics(),
              itemCount: 10,
              itemBuilder: (context, index) {
                return Container(
                  padding: EdgeInsets.symmetric(horizontal: 5, vertical: 5),
                  // 移除固定宽度,或改为width: double.infinity占满父容器
                  child: ProductWidgetWebShimmer(),
                );
              },
            )
          : GridView.builder(
              shrinkWrap: true,
              gridDelegate: ResponsiveHelper.isDesktop(context)
                  ? SliverGridDelegateWithMaxCrossAxisExtent(
                      maxCrossAxisExtent: 195, mainAxisExtent: 250)
                  : SliverGridDelegateWithFixedCrossAxisCount(
                      crossAxisSpacing: 5,
                      mainAxisSpacing: 5,
                      childAspectRatio: 4,
                      crossAxisCount: ResponsiveHelper.isDesktop(context)
                          ? 3
                          : ResponsiveHelper.isTab(context)
                              ? 2
                              : 1,
                    ),
              itemCount: 12,
              itemBuilder: (BuildContext context, int index) {
                return ResponsiveHelper.isDesktop(context)
                    ? ProductWidgetWebShimmer()
                    : ProductShimmer(isEnabled: productList == null);
              },
              padding: EdgeInsets.symmetric(
                  horizontal: Dimensions.PADDING_SIZE_SMALL),
            );
    }
    if (productList.length == 0) {
      return SizedBox();
    }

    return productType == ProductType.POPULAR_PRODUCT
        ? ListView.builder(
            scrollDirection: Axis.vertical, // 改为纵向滚动
            shrinkWrap: true, // 自适应内容高度
            physics: BouncingScrollPhysics(),
            itemCount: productList.length,
            itemBuilder: (context, index) {
              return Container(
                padding: EdgeInsets.symmetric(horizontal: 5, vertical: 5),
                // 移除固定宽度,或改为width: double.infinity占满父容器
                child: ProductWidgetWeb(
                    product: productList[index], fromPopularItem: true),
              );
            },
          )
        : Column(children: [
            GridView.builder(
              gridDelegate: ResponsiveHelper.isDesktop(context)
                  ? SliverGridDelegateWithMaxCrossAxisExtent(
                      maxCrossAxisExtent: 195, mainAxisExtent: 250)
                  : SliverGridDelegateWithFixedCrossAxisCount(
                      crossAxisSpacing: 5,
                      mainAxisSpacing: 5,
                      childAspectRatio: 3.5,
                      crossAxisCount: ResponsiveHelper.isTab(context) ? 2 : 1,
                    ),
              itemCount: productList.length,
              padding: EdgeInsets.symmetric(
                  horizontal: Dimensions.PADDING_SIZE_EXTRA_SMALL),
              physics: NeverScrollableScrollPhysics(),
              shrinkWrap: true,
              itemBuilder: (BuildContext context, int index) {
                return ResponsiveHelper.isDesktop(context)
                    ? Padding(
                        padding: const EdgeInsets.all(5.0),
                        child: ProductWidgetWeb(product: productList[index]),
                      )
                    : ProductWidget(product: productList[index]);
              },
            ),
            SizedBox(height: 30),
            productList != null
                ? Padding(
                    padding: ResponsiveHelper.isDesktop(context)
                        ? const EdgeInsets.only(top: 40, bottom: 70)
                        : const EdgeInsets.all(0),
                    child: ResponsiveHelper.isDesktop(context)
                        ? prodProvider.isLoading
                            ? Center(
                                child: Padding(
                                  padding: EdgeInsets.all(
                                      Dimensions.PADDING_SIZE_SMALL),
                                  child: CircularProgressIndicator(
                                      valueColor: AlwaysStoppedAnimation<Color>(
                                          Theme.of(context).primaryColor)),
                                ),
                              )
                            : (_productProvider.latestOffset ==
                                    (Provider.of<ProductProvider>(context,
                                                listen: false)
                                            .latestPageSize /
                                        10)
                                        .ceil())
                                ? SizedBox()
                                : SizedBox(
                                    width: 500,
                                    child: ElevatedButton(
                                      style: ElevatedButton.styleFrom(
                                        primary: Theme.of(context).primaryColor,
                                        shape: RoundedRectangleBorder(
                                            borderRadius:
                                                BorderRadius.circular(30)),
                                      ),
                                      onPressed: () {
                                        _productProvider.moreProduct(context);
                                      },
                                      child: Padding(
                                        padding: const EdgeInsets.symmetric(
                                            vertical: 10),
                                        child: Text(
                                            getTranslated('see_more', context),
                                            style: poppinsRegular.copyWith(
                                                fontSize: Dimensions
                                                    .FONT_SIZE_OVER_LARGE)),
                                      ),
                                    ),
                                  )
                        : prodProvider.isLoading
                            ? Center(
                                child: Padding(
                                  padding: EdgeInsets.all(
                                      Dimensions.PADDING_SIZE_SMALL),
                                  child: CircularProgressIndicator(
                                      valueColor: AlwaysStoppedAnimation<Color>(
                                          Theme.of(context).primaryColor)),
                                ),
                              )
                            : SizedBox.shrink(),
                  )
                : SizedBox.shrink(),
          ]);
  },
);

补充说明

  • 如果不需要纵向列表滚动,可把physics: BouncingScrollPhysics()改为NeverScrollableScrollPhysics()
  • 最新产品(LATEST_PRODUCT)模块本身就是纵向布局,无需修改

内容的提问来源于stack exchange,提问作者elgunismayiloff

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.26 07:07:02