(https://i.sstatic.net/3fuhjClD.png)
看图片,我当前的卡片样式不正确。模糊效果堆叠在整个卡片上,而不是仅在卡片的中间 1/3 处。
下图是它应该的样子。 (https://i.sstatic.net/ykoZTwd0.png)
import 'dart:ui';
import 'package:flutter/material.dart';
import 'package:google_fonts/google_fonts.dart';
import 'package:trailx_app/const/colors.dart';
class FypHikingCards extends StatefulWidget {
const FypHikingCards({super.key});
@override
State<FypHikingCards> createState() => _FypHikingCards();
}
class _FypHikingCards extends State<FypHikingCards> {
final List<String> images =
List<String>.generate(8, (index) => "Item $index");
final List<String> imagePaths = [
'assets/images/hiking_0.png',
'assets/images/hiking_1.png',
'assets/images/hiking_2.png',
'assets/images/hiking_3.png',
'assets/images/hiking_4.png',
'assets/images/hiking_5.png',
'assets/images/hiking_6.png',
'assets/images/hiking_7.png'
];
final List<bool> liked = List<bool>.filled(8, false);
@override
Widget build(BuildContext context) {
return GridView.builder(
gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 2,
crossAxisSpacing: 2.0,
mainAxisSpacing: 2.0,
childAspectRatio: 2 / 2.2,
),
itemCount: 8,
itemBuilder: (context, index) {
return Center(
child: Stack(
children: [
Card(
clipBehavior: Clip.antiAliasWithSaveLayer,
elevation: 2,
child: Column(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
// This part holds the image with the blur at the bottom 1/3
Expanded(
flex: 2,
child: Stack(
children: [
// Full image in the background
Positioned.fill(
child: Image.asset(
imagePaths[index],
fit: BoxFit.fill,
width: double.infinity,
),
),
// Blur the bottom part of the image with a fixed height
Positioned(
bottom: 0,
left: 0,
right: 0,
child: BackdropFilter(
filter: ImageFilter.blur(sigmaX: 10, sigmaY: 10),
child: Container(
color: Colors.black.withOpacity(
0), // Transparent container for blur
),
),
),
],
),
),
// Text information in the white box
Padding(
padding: const EdgeInsets.all(8.0),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: [
SizedBox(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
"Length",
style: GoogleFonts.getFont('Inter',
color: Colors.black,
fontSize: 8,
fontWeight: FontWeight.w500),
),
Text(
"1.69 Mi",
style: GoogleFonts.getFont('Inter',
color: loginGreenColor,
fontSize: 12,
fontWeight: FontWeight.w600),
),
Text(
"Duration",
style: GoogleFonts.getFont('Inter',
color: Colors.black,
fontSize: 8,
fontWeight: FontWeight.w500),
),
Text(
"1.5 Hr",
style: GoogleFonts.getFont('Inter',
color: loginGreenColor,
fontSize: 12,
fontWeight: FontWeight.w600),
),
],
),
),
SizedBox(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
"Distance",
style: GoogleFonts.getFont('Inter',
color: Colors.black,
fontSize: 8,
fontWeight: FontWeight.w500),
),
Text(
"6,321 Ft",
style: GoogleFonts.getFont('Inter',
color: loginGreenColor,
fontSize: 12,
fontWeight: FontWeight.w600),
),
Text(
"Difficulty",
style: GoogleFonts.getFont('Inter',
color: Colors.black,
fontSize: 8,
fontWeight: FontWeight.w500),
),
Text(
"Medium",
style: GoogleFonts.getFont('Inter',
color: loginGreenColor,
fontSize: 12,
fontWeight: FontWeight.w600),
),
],
),
),
],
),
),
],
),
),
Positioned(
top: 0,
right: 0,
child: IconButton(
color: likedColor,
icon: liked[index]
? const Icon(Icons.favorite)
: const Icon(
Icons.favorite_border,
),
onPressed: () {
setState(() {
liked[index] = !liked[index];
});
},
),
),
],
),
);
},
);
}
}
我的白色部分是正确的,但我只是不确定如何在白色框顶部设置模糊效果的样式。
试试这个:
使用的套件:
[assorted_layout_widgets][1]
[模糊][2]
[自动高度网格视图][3]
注意:将 CachedNetworkImage() 替换为 Image.asset()
import 'package:assorted_layout_widgets/assorted_layout_widgets.dart';
import 'package:auto_height_grid_view/auto_height_grid_view.dart';
import 'package:blur/blur.dart';
import 'package:cached_network_image/cached_network_image.dart';
import 'package:flutter/material.dart';
void main() {
runApp(const MyApp());
}
// ignore: must_be_immutable
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return const MaterialApp(home: MainScreen());
}
}
class MainScreen extends StatefulWidget {
const MainScreen({super.key});
@override
State<MainScreen> createState() => _MainScreenState();
}
class _MainScreenState extends State<MainScreen> {
final List<String> images = [
"https://images.pexels.com/photos/1658967/pexels-photo-1658967.jpeg?auto=compress&cs=tinysrgb&w=1260&h=750&dpr=2",
"https://images.pexels.com/photos/1006121/pexels-photo-1006121.jpeg?auto=compress&cs=tinysrgb&w=1260&h=750&dpr=2",
"https://images.pexels.com/photos/994605/pexels-photo-994605.jpeg?auto=compress&cs=tinysrgb&w=1260&h=750&dpr=2",
"https://images.pexels.com/photos/1624438/pexels-photo-1624438.jpeg?auto=compress&cs=tinysrgb&w=1260&h=750&dpr=2",
"https://images.pexels.com/photos/1166209/pexels-photo-1166209.jpeg?auto=compress&cs=tinysrgb&w=1260&h=750&dpr=2",
"https://images.pexels.com/photos/1761279/pexels-photo-1761279.jpeg?auto=compress&cs=tinysrgb&w=1260&h=750&dpr=2",
"https://images.pexels.com/photos/1559393/pexels-photo-1559393.jpeg?auto=compress&cs=tinysrgb&w=1260&h=750&dpr=2",
"https://images.pexels.com/photos/1808329/pexels-photo-1808329.jpeg?auto=compress&cs=tinysrgb&w=1260&h=750&dpr=2",
];
@override
Widget build(BuildContext context) {
return Scaffold(
body: SafeArea(
child: AutoHeightGridView(
crossAxisCount: 2,
mainAxisSpacing: 10,
itemCount: images.length,
builder: (context, index) {
return MyWidget(
url: images[index],
);
},
)),
);
}
}
class MyWidget extends StatelessWidget {
const MyWidget({super.key, required this.url});
final String url;
@override
Widget build(BuildContext context) {
return Material(
elevation: 10,
borderRadius: BorderRadius.circular(15),
child: ColumnSuper(
innerDistance: -80,
children: [
ClipRRect(
borderRadius: BorderRadius.circular(15),
//Image.asset
child: CachedNetworkImage(
imageUrl: url,
fit: BoxFit.fill,
height: 250,
width: double.infinity,
),
),
Column(
children: [
ClipRRect(
borderRadius: const BorderRadius.only(
topLeft: Radius.circular(15),
topRight: Radius.circular(15)),
child: Container(
width: double.infinity,
padding:
const EdgeInsets.symmetric(vertical: 5, horizontal: 10),
child: const Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [Text('White Mountain'), Text("Lincoln, NH")],
),
).frosted(
blur: 6, //handle blur
),
),
ClipRRect(
borderRadius: const BorderRadius.only(
bottomLeft: Radius.circular(15),
bottomRight: Radius.circular(15)),
child: Container(
padding: const EdgeInsets.all(10),
color: Colors.white,
child: const Row(
children: [
Expanded(
flex: 1,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [Text("Length"), Text("1.69 mi")],
)),
Expanded(
flex: 1,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [Text("Distance"), Text("4,847 ft")],
)),
],
),
),
),
],
)
],
),
);
}
}
```[![enter image description here][4]][4]
[1]: https://pub.dev/packages/assorted_layout_widgets
[2]: https://pub.dev/packages/blur
[3]: https://pub.dev/packages/auto_height_grid_view
[4]: https://i.sstatic.net/BOPUmFwz.png