如何按预期设计卡片样式,1/3 为白色背景,1/3 为模糊,其余为常规图片

问题描述 投票:0回答:1

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];
                    });
                  },
                ),
              ),
            ],
          ),
        );
      },
    );
  }
}

我的白色部分是正确的,但我只是不确定如何在白色框顶部设置模糊效果的样式。

flutter dart frontend
1个回答
0
投票

试试这个:

使用的套件:

  1. [assorted_layout_widgets][1]

  2. [模糊][2]

  3. [自动高度网格视图][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
© www.soinside.com 2019 - 2024. All rights reserved.