效果图

实现步骤
1.构建网格通用子项
Dart
Widget _buildInAudioItem({
required String name,
required List<String> images, //关键:使用列表存储图片
required VoidCallback onTap,
double imageSize = 40,
}){
return Column(
children: [
GestureDetector(
onTap: onTap,
child: Container(
height: 150,
width: 155,
decoration: BoxDecoration(
color:Color(0xFF1B1D2E),
borderRadius: BorderRadius.circular(10)
),
child: Center(
child: _buildImageLayout(images,imageSize:imageSize), //关键:传递图片和图片尺寸给显示图片的方法
),
),
),
SizedBox(height: 8),
Text(name,style: TextStyle(color: Colors.white,fontSize: 12),),
],
);
}
2.构建图片的布局,根据用户传递的图片个数传递不同的UI格式
Dart
Widget _buildImageLayout(List<String> images, {double imageSize = 40}) {
int count = images.length; //传递的图片个数
if (count == 1) {
// 单个图片居中显示
return Container(
height: imageSize,
width: imageSize,
decoration: BoxDecoration(
color: Color(0xFF55596D),
borderRadius: BorderRadius.circular(imageSize / 2),
),
child: Center(
child: Image.asset(
images[0],
width: imageSize * 0.5,
height: imageSize * 0.5,
),
),
);
} else if (count == 2) {
// 两个图片并排
return Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
_buildSingleImage(images[0], imageSize: imageSize),
SizedBox(width: 5,),
_buildSingleImage(images[1], imageSize: imageSize),
],
);
} else if (count == 3) {
// 三个或以上图片,显示前三个
return Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
_buildSingleImage(images[0], imageSize: imageSize),
SizedBox(width: 5,),
_buildSingleImage(images[1], imageSize: imageSize),
SizedBox(width: 5,),
_buildSingleImage(images[2], imageSize: imageSize),
],
);
}
return SizedBox.shrink();
}
3.构建单个图片的组件:用圆包裹传递过来的图片
Dart
Widget _buildSingleImage(String imagePath, {double imageSize = 40}) {
return Container(
height: imageSize,
width: imageSize,
decoration: BoxDecoration(
color: Color(0xFF55596D),
borderRadius: BorderRadius.circular(imageSize / 2),
),
child: Center(
child: Image.asset(
imagePath,
width: imageSize * 0.5,
height: imageSize * 0.5,
),
),
);
}
4.使用网格列表构建整个列表UI
Dart
Widget buildInAudioList() {
return Expanded(
child: Padding(
padding: EdgeInsets.symmetric(horizontal: 10,vertical: 40),
child: GridView.count(
crossAxisCount: 2,//固定列数
crossAxisSpacing: 15,//列间距
mainAxisSpacing: 20,//行间距
childAspectRatio: 155/170,//子项的宽高比
children: [
_buildInAudioItem(
name: "苹果",
images: ["assets/images/apple.png"],
onTap: () => print("点击苹果"),
),
_buildInAudioItem(
name: "苹果+香蕉",
images: ["assets/images/apple.png", "assets/images/banana.png"],
onTap: () => print("点击苹果+香蕉"),
),
_buildInAudioItem(
name: "苹果、香蕉和樱桃",
images: ["assets/images/apple.png", "assets/images/banana.png", "assets/images/cherry.png"],
onTap: () => print("点击苹果、香蕉和樱桃"),
),
_buildInAudioItem(
name: "苹果",
images: ["assets/images/apple.png"],
onTap: () => print("点击苹果"),
),
],
),
),
);
}
5.整个背景图
Dart
@override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.transparent,
body: Container(
width: double.infinity,
height: double.infinity,
decoration: const BoxDecoration(
gradient: LinearGradient(
begin: Alignment.topCenter,
end: Alignment.bottomCenter,
colors: [
Color(0xFF060618),
Color(0xFF070A23),
],
),
),
child: Expanded( // 使用Expanded包裹GridView
child: buildInAudioList(),
),
),
);
}
代码实例
Dart
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
class DemoPage extends StatefulWidget {
const DemoPage({
super.key,
});
@override
State<DemoPage> createState() => _DemoPageState();
}
class _DemoPageState extends State<DemoPage> {
@override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.transparent,
body: Container(
width: double.infinity,
height: double.infinity,
decoration: const BoxDecoration(
gradient: LinearGradient(
begin: Alignment.topCenter,
end: Alignment.bottomCenter,
colors: [
Color(0xFF060618),
Color(0xFF070A23),
],
),
),
child: Expanded( // 使用Expanded包裹GridView
child: buildInAudioList(),
),
),
);
}
Widget buildInAudioList() {
return Expanded(
child: Padding(
padding: EdgeInsets.symmetric(horizontal: 10,vertical: 40),
child: GridView.count(
crossAxisCount: 2,//固定列数
crossAxisSpacing: 15,//列间距
mainAxisSpacing: 20,//行间距
childAspectRatio: 155/170,//子项的宽高比
children: [
_buildInAudioItem(
name: "苹果",
images: ["assets/images/apple.png"],
onTap: () => print("点击苹果"),
),
_buildInAudioItem(
name: "苹果+香蕉",
images: ["assets/images/apple.png", "assets/images/banana.png"],
onTap: () => print("点击苹果+香蕉"),
),
_buildInAudioItem(
name: "苹果、香蕉和樱桃",
images: ["assets/images/apple.png", "assets/images/banana.png", "assets/images/cherry.png"],
onTap: () => print("点击苹果、香蕉和樱桃"),
),
_buildInAudioItem(
name: "苹果",
images: ["assets/images/apple.png"],
onTap: () => print("点击苹果"),
),
],
),
),
);
}
//网格子项
Widget _buildInAudioItem({
required String name,
required List<String> images, //关键:使用列表存储图片
required VoidCallback onTap,
double imageSize = 40,
}){
return Column(
children: [
GestureDetector(
onTap: onTap,
child: Container(
height: 150,
width: 155,
decoration: BoxDecoration(
color:Color(0xFF1B1D2E),
borderRadius: BorderRadius.circular(10)
),
child: Center(
child: _buildImageLayout(images,imageSize:imageSize), //关键:传递图片和图片尺寸给显示图片的方法
),
),
),
SizedBox(height: 8),
Text(name,style: TextStyle(color: Colors.white,fontSize: 12),),
],
);
}
// 构建图片布局
Widget _buildImageLayout(List<String> images, {double imageSize = 40}) {
int count = images.length; //传递的图片个数
if (count == 1) {
// 单个图片居中显示
return Container(
height: imageSize,
width: imageSize,
decoration: BoxDecoration(
color: Color(0xFF55596D),
borderRadius: BorderRadius.circular(imageSize / 2),
),
child: Center(
child: Image.asset(
images[0],
width: imageSize * 0.5,
height: imageSize * 0.5,
),
),
);
} else if (count == 2) {
// 两个图片并排
return Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
_buildSingleImage(images[0], imageSize: imageSize),
SizedBox(width: 5,),
_buildSingleImage(images[1], imageSize: imageSize),
],
);
} else if (count == 3) {
// 三个或以上图片,显示前三个
return Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
_buildSingleImage(images[0], imageSize: imageSize),
SizedBox(width: 5,),
_buildSingleImage(images[1], imageSize: imageSize),
SizedBox(width: 5,),
_buildSingleImage(images[2], imageSize: imageSize),
],
);
}
return SizedBox.shrink();
}
// 单个图片组件
Widget _buildSingleImage(String imagePath, {double imageSize = 40}) {
return Container(
height: imageSize,
width: imageSize,
decoration: BoxDecoration(
color: Color(0xFF55596D),
borderRadius: BorderRadius.circular(imageSize / 2),
),
child: Center(
child: Image.asset(
imagePath,
width: imageSize * 0.5,
height: imageSize * 0.5,
),
),
);
}
}