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
相关产品推荐
相关产品推荐

