詳解Flutter如何在單個屏幕上實現(xiàn)多個列表
前言
今天,我將提供一個實際的示例,演示如何在單個頁面上實現(xiàn)多個列表,這些列表可以水平排列、網(wǎng)格格式、垂直排列,甚至是這些常用布局的組合。
下面是要做的:
實現(xiàn)
讓我們從創(chuàng)建一個包含產(chǎn)品所有屬性的產(chǎn)品模型開始。
class Product { final String id; final String name; final double price; final String image; const Product({ required this.id, required this.name, required this.price, required this.image, }); factory Product.fromJson(Map json) { return Product( id: json['id'], name: json['name'], price: json['price'], image: json['image'], ); } }
現(xiàn)在,我們將設(shè)計我們的小部件以支持水平、垂直和網(wǎng)格視圖。
創(chuàng)建一個名為 HorizontalRawWidget 的新窗口小部件類,定義水平列表的用戶界面。
import 'package:flutter/material.dart'; import 'package:multiple_listview_example/models/product.dart'; class HorizontalRawWidget extends StatelessWidget { final Product product; const HorizontalRawWidget({Key? key, required this.product}) : super(key: key); @override Widget build(BuildContext context) { return Padding( padding: const EdgeInsets.only( left: 15, ), child: Container( width: 125, decoration: BoxDecoration( color: Colors.white, borderRadius: BorderRadius.circular(12)), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Padding( padding: const EdgeInsets.fromLTRB(5, 5, 5, 0), child: ClipRRect( borderRadius: BorderRadius.circular(12), child: Image.network( product.image, height: 130, fit: BoxFit.contain, ), ), ), Expanded( child: Padding( padding: const EdgeInsets.all(8.0), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Expanded( child: Text(product.name, maxLines: 2, overflow: TextOverflow.ellipsis, style: const TextStyle( color: Colors.black, fontSize: 12, fontWeight: FontWeight.bold)), ), Row( crossAxisAlignment: CrossAxisAlignment.end, children: [ Text("\$${product.price}", style: const TextStyle( color: Colors.black, fontSize: 12)), ], ), ], ), ), ) ], ), ), ); } }
設(shè)計一個名為 GridViewRawWidget 的小部件類,定義單個網(wǎng)格視圖的用戶界面。
import 'package:flutter/material.dart'; import 'package:multiple_listview_example/models/product.dart'; class GridViewRawWidget extends StatelessWidget { final Product product; const GridViewRawWidget({Key? key, required this.product}) : super(key: key); @override Widget build(BuildContext context) { return Container( padding: const EdgeInsets.all(5), decoration: BoxDecoration( color: Colors.white, borderRadius: BorderRadius.circular(10)), child: Column( children: [ AspectRatio( aspectRatio: 1, child: ClipRRect( borderRadius: BorderRadius.circular(10), child: Image.network( product.image, fit: BoxFit.fill, ), ), ) ], ), ); } }
最后,讓我們?yōu)榇怪币晥D創(chuàng)建一個小部件類。
import 'package:flutter/material.dart'; import 'package:multiple_listview_example/models/product.dart'; class VerticalRawWidget extends StatelessWidget { final Product product; const VerticalRawWidget({Key? key, required this.product}) : super(key: key); @override Widget build(BuildContext context) { return Container( margin: const EdgeInsets.symmetric(horizontal: 15, vertical: 5), padding: const EdgeInsets.symmetric(horizontal: 10, vertical: 10), color: Colors.white, child: Row( children: [ Image.network( product.image, width: 78, height: 88, ), const SizedBox( width: 15, ), Expanded( child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( product.name, style: const TextStyle(fontSize: 12, color: Colors.black, fontWeight: FontWeight.bold), ), SizedBox( height: 5, ), Text("\$${product.price}", style: const TextStyle(color: Colors.black, fontSize: 12)), ], ), ) ], ), ); } }
現(xiàn)在是時候把所有的小部件合并到一個屏幕中了,我們先創(chuàng)建一個名為“home_page.dart”的頁面,在這個頁面中,我們將使用一個橫向的 ListView、縱向的 ListView 和 GridView。
import 'package:flutter/material.dart'; import 'package:multiple_listview_example/models/product.dart'; import 'package:multiple_listview_example/utils/product_helper.dart'; import 'package:multiple_listview_example/views/widgets/gridview_raw_widget.dart'; import 'package:multiple_listview_example/views/widgets/horizontal_raw_widget.dart'; import 'package:multiple_listview_example/views/widgets/title_widget.dart'; import 'package:multiple_listview_example/views/widgets/vertical_raw_widget.dart'; class HomePage extends StatelessWidget { const HomePage({Key? key}) : super(key: key); @override Widget build(BuildContext context) { List products = ProductHelper.getProductList(); return Scaffold( backgroundColor: const Color(0xFFF6F5FA), appBar: AppBar( centerTitle: true, title: const Text("Home"), ), body: SingleChildScrollView( child: Container( padding: const EdgeInsets.symmetric(vertical: 20), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ const TitleWidget(title: "Horizontal List"), const SizedBox( height: 10, ), SizedBox( height: 200, child: ListView.builder( shrinkWrap: true, scrollDirection: Axis.horizontal, itemCount: products.length, itemBuilder: (BuildContext context, int index) { return HorizontalRawWidget( product: products[index], ); }), ), const SizedBox( height: 10, ), const TitleWidget(title: "Grid View"), Container( padding: const EdgeInsets.symmetric(horizontal: 15, vertical: 10), child: GridView.builder( gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount( crossAxisCount: 2, crossAxisSpacing: 13, mainAxisSpacing: 13, childAspectRatio: 1), itemCount: products.length, shrinkWrap: true, physics: const NeverScrollableScrollPhysics(), itemBuilder: (BuildContext context, int index) { return GridViewRawWidget( product: products[index], ); }), ), const TitleWidget(title: "Vertical List"), ListView.builder( itemCount: products.length, shrinkWrap: true, physics: const NeverScrollableScrollPhysics(), itemBuilder: (BuildContext context, int index) { return VerticalRawWidget( product: products[index], ); }), ], ), ), ), ); } }
我使用了一個 SingleChildScrollView
widget 作為代碼中的頂部根 widget,考慮到我整合了多個布局,如水平列表、網(wǎng)格視圖和垂直列表,我將所有這些 widget 包裝在一個 Column
widget 中。
挑戰(zhàn)在于如何處理多個滾動部件,因為在上述示例中有兩個垂直滾動部件:一個網(wǎng)格視圖和一個垂直列表視圖。為了禁用單個部件的滾動行為, physics
屬性被設(shè)置為 const NeverScrollableScrollPhysics()
。取而代之的是,使用頂層根 SingleChildScrollView
` 來啟用整個內(nèi)容的滾動。此外, SingleChildScrollView
上的shrinkWrap
屬性被設(shè)置為true
,以確保它能緊緊包裹其內(nèi)容,只占用其子控件所需的空間。
Github 鏈接:https://github.com/tarunaronno005/flutter-multiple-listview
到此這篇關(guān)于詳解Flutter如何在單個屏幕上實現(xiàn)多個列表的文章就介紹到這了,更多相關(guān)Flutter單個屏幕實現(xiàn)多個列表內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Android實現(xiàn)點擊WebView界面中圖片滑動瀏覽與保存圖片功能
大家在日常使用spp流量文章的時候經(jīng)常會遇到這樣的一個功能,點擊文章的圖片進(jìn)入圖片的瀏覽模式,可以左右滑動圖片瀏覽,并且可以實現(xiàn)保存圖片的功能,所以本文主要就介紹了在Android如何實現(xiàn)點擊WebView界面中圖片滑動瀏覽與保存圖片功能,需要的朋友可以參考下。2017-04-04Android編程開發(fā)之seekBar采用handler消息處理操作的方法
這篇文章主要介紹了Android編程開發(fā)之seekBar采用handler消息處理操作的方法,結(jié)合實例分析了Android實現(xiàn)進(jìn)度條功能的相關(guān)技巧,需要的朋友可以參考下2015-12-12Android廣播接實現(xiàn)監(jiān)聽電話狀態(tài)(電話的狀態(tài),攔截)
這篇文章主要介紹了Android廣播接實現(xiàn)監(jiān)聽電話狀態(tài)(電話的狀態(tài),攔截) 的相關(guān)資料,需要的朋友可以參考下2016-03-03