如何浏览项目高度使动态扑来

发布于 2025-02-07 09:46:00 字数 10156 浏览 4 评论 0原文

我开始学习扑朔迷离的语言,我想在GridView中显示产品列表。但是有一个问题。 当我运行时,应用程序浏览项目的显示完美,就像下图一样。

  • 但是,当我关闭应用程序并再次打开应用程序时(请注意不运行),然后我得到了底部的溢出错误。图像在下面。

  • 我的代码是
class HomePage extends StatefulWidget {
  @override
  State<HomePage> createState() => _HomePageState();
}

class _HomePageState extends State<HomePage> {
  @override
  void initState() {
    // TODO: implement initState
    super.initState();
    loadData();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text(
          "Catalog App",
        ),
      ),
      body: (CatalogModel.products != null && CatalogModel.products!.isNotEmpty)
          ? Padding(
              padding: const EdgeInsets.all(1.0),
              child: GridView.builder(
                gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
                  crossAxisCount: 2,
                  childAspectRatio: MediaQuery.of(context).size.width /
                      (MediaQuery.of(context).size.height / 1.06),
                ),
                shrinkWrap: true,
                itemBuilder: (context, index) {
                  CatalogItem item = CatalogModel.products![index];
                  return Expanded(
                    child: InkWell(
                      onTap: () => Navigator.push(
                          context,
                          MaterialPageRoute(
                              builder: (context) =>
                                  ProductDetails(item: item))),
                      child: Padding(
                        padding: const EdgeInsets.all(1.0),
                        child: Container(
                          decoration: const BoxDecoration(
                            color: Colors.white,
                          ),
                          child: Column(
                            children: [
                              SizedBox(
                                width: double.infinity,
                                height: 220,
                                child: Image.network(item.image,
                                    fit: BoxFit.cover),
                              ),
                              Padding(
                                  padding: const EdgeInsets.all(10.0),
                                  child: Column(children: [
                                    SizedBox(
                                      width: double.infinity,
                                      child: Text(item.name,
                                          textAlign: TextAlign.start,
                                          overflow: TextOverflow.ellipsis,
                                          style: GoogleFonts.cabin(
                                              fontSize: 16.0,
                                              textStyle: const TextStyle(
                                                fontWeight: FontWeight.bold,
                                              ))),
                                    ),
                                    Padding(
                                      padding: const EdgeInsets.only(top: 5.0),
                                      child: SizedBox(
                                        width: double.infinity,
                                        child: Text(item.category,
                                            textAlign: TextAlign.start,
                                            style: GoogleFonts.cabin(
                                                textStyle: const TextStyle(
                                                    fontWeight: FontWeight.bold,
                                                    fontSize: 11.0,
                                                    color: Color(0xFF808080)))),
                                      ),
                                    ),
                                    PriceDetailsWidget(
                                        discount: item.discount,
                                        actual_price: item.actual_price,
                                        price: item.price),
                                    const AddToCartWidget(),
                                  ])),
                            ],
                          ),
                        ),
                      ),
                    ),
                  );
                },
                itemCount: CatalogModel.products?.length,
              ),
            )
          : const Center(
              child: CircularProgressIndicator(),
            ),
      drawer: MyDrawer(),
    );
  }

  void loadData() async {
    await Future.delayed(Duration(seconds: 5));
    final catalogJson =
        await rootBundle.loadString("assets/files/products.json");
    final decodedData = jsonDecode(catalogJson);
    final productData = decodedData["products"];
    CatalogModel.products = List.from(productData)
        .map<CatalogItem>((item) => CatalogItem.fromMap(item))
        .toList();
    setState(() {});
  }
}

pricedetailswidget.dart

class PriceDetailsWidget extends StatelessWidget {
  final String discount;
  final num price, actual_price;
  const PriceDetailsWidget({
    Key? key,
    required this.discount,
    required this.actual_price,
    required this.price,
  }) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Padding(
      padding: const EdgeInsets.only(top: 8.0),
      child: SizedBox(
        width: double.infinity,
        child: Row(
          crossAxisAlignment: CrossAxisAlignment.start,
          children: [
            Text("\$${price}",
                textAlign: TextAlign.start,
                style: GoogleFonts.cabin(
                    textStyle: const TextStyle(
                        fontWeight: FontWeight.normal,
                        fontSize: 14.0,
                        decoration: TextDecoration.lineThrough,
                        decorationColor: Color(0xFF808080),
                        decorationThickness: 3.0,
                        color: Color(0xFF808080)))),
            Padding(
              padding: const EdgeInsets.only(left: 5.0),
              child: Text(
                "\$${actual_price}",
                style: const TextStyle(
                  color: Color(MyTheme.primaryColor),
                  fontWeight: FontWeight.bold,
                  fontSize: 14.0,
                ),
              ),
            ),
            Padding(
              padding: const EdgeInsets.only(left: 5.0),
              child: Text(
                discount,
                style: const TextStyle(
                  color: Colors.red,
                  fontWeight: FontWeight.normal,
                  fontSize: 14.0,
                ),
              ),
            )
          ],
        ),
      ),
    );
  }
}

addtocartwidget.dart

class AddToCartWidget extends StatelessWidget {
  const AddToCartWidget({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return ElevatedButton(
      onPressed: () {},
      style: ElevatedButton.styleFrom(elevation: 0.0, padding: EdgeInsets.zero),
      child: Row(
        mainAxisSize: MainAxisSize.max,
        mainAxisAlignment: MainAxisAlignment.center,
        crossAxisAlignment: CrossAxisAlignment.center,
        children: const [
          Icon(
            // <-- Icon
            CupertinoIcons.cart_fill,
            size: 24.0,
          ),
          SizedBox(
            width: 5,
          ),
          Text('Add to cart'), // <-- Text
        ],
      ),
    );
  }
}

catalogmodel&amp; ETALOGITEM

class CatalogModel {
  static List<CatalogItem>? products;
}

class CatalogItem {
  final String id;
  final String name;
  final String desc;
  final num price;
  final num actual_price;
  final String discount;
  final String color;
  final String image;
  final String category;
  CatalogItem(
      {required this.id,
      required this.name,
      required this.desc,
      required this.price,
      required this.actual_price,
      required this.discount,
      required this.color,
      required this.image,
      required this.category});

  factory CatalogItem.fromMap(Map<String, dynamic> map) => CatalogItem(
      id: map["id"],
      name: map["name"],
      desc: map["desc"],
      price: map["price"],
      actual_price: map["actual_price"],
      discount: map["discount"],
      color: map["color"],
      image: map["image"],
      category: map["category"]);

  toMap() => {
        "id": id,
        "name": name,
        "desc": desc,
        "price": price,
        "color": color,
        "image": image,
      };
}

products.json 我存储在资产文件夹中的文件

{
    "products": [
        {
            "id": "prod001",
            "name": "iPhone 13 Pro",
            "desc": "Your iPhone will arrive.",
            "price": 1299,
            "actual_price": 999,
            "discount": "20% off",
            "color": "#536858",
            "image": "https://d2xamzlzrdbdbn.cloudfront.net/products/66d6056e-e588-4b03-a44b-74685197003622111313.jpg",
            "category": "Mobile"
        },
        {
            "id": "prod002",
            "name": "iPhone SE (PRODUCT) RED",
            "desc": "iPhone SE (PRODUCT) RED",
            "price": 429,
            "actual_price": 399,
            "discount": "15% off",
            "color": "#A7090A",
            "image": "https://www.neolight.in/wp-content/uploads/2022/01/iPhone_XR_red.jpg",
            "category": "Mobile"
        }
    ]
}

I'm starting to learn the flutter language and I want to display the product list in GridView. But there is one problem that arises.
When I run the app GridView items are displayed perfectly like the below image.

Without bottom overflow error

  • But when I close the app and open it again (note without the run) then I got a bottom overflow error. The image is below.

enter image description here

  • My Code is this
class HomePage extends StatefulWidget {
  @override
  State<HomePage> createState() => _HomePageState();
}

class _HomePageState extends State<HomePage> {
  @override
  void initState() {
    // TODO: implement initState
    super.initState();
    loadData();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text(
          "Catalog App",
        ),
      ),
      body: (CatalogModel.products != null && CatalogModel.products!.isNotEmpty)
          ? Padding(
              padding: const EdgeInsets.all(1.0),
              child: GridView.builder(
                gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
                  crossAxisCount: 2,
                  childAspectRatio: MediaQuery.of(context).size.width /
                      (MediaQuery.of(context).size.height / 1.06),
                ),
                shrinkWrap: true,
                itemBuilder: (context, index) {
                  CatalogItem item = CatalogModel.products![index];
                  return Expanded(
                    child: InkWell(
                      onTap: () => Navigator.push(
                          context,
                          MaterialPageRoute(
                              builder: (context) =>
                                  ProductDetails(item: item))),
                      child: Padding(
                        padding: const EdgeInsets.all(1.0),
                        child: Container(
                          decoration: const BoxDecoration(
                            color: Colors.white,
                          ),
                          child: Column(
                            children: [
                              SizedBox(
                                width: double.infinity,
                                height: 220,
                                child: Image.network(item.image,
                                    fit: BoxFit.cover),
                              ),
                              Padding(
                                  padding: const EdgeInsets.all(10.0),
                                  child: Column(children: [
                                    SizedBox(
                                      width: double.infinity,
                                      child: Text(item.name,
                                          textAlign: TextAlign.start,
                                          overflow: TextOverflow.ellipsis,
                                          style: GoogleFonts.cabin(
                                              fontSize: 16.0,
                                              textStyle: const TextStyle(
                                                fontWeight: FontWeight.bold,
                                              ))),
                                    ),
                                    Padding(
                                      padding: const EdgeInsets.only(top: 5.0),
                                      child: SizedBox(
                                        width: double.infinity,
                                        child: Text(item.category,
                                            textAlign: TextAlign.start,
                                            style: GoogleFonts.cabin(
                                                textStyle: const TextStyle(
                                                    fontWeight: FontWeight.bold,
                                                    fontSize: 11.0,
                                                    color: Color(0xFF808080)))),
                                      ),
                                    ),
                                    PriceDetailsWidget(
                                        discount: item.discount,
                                        actual_price: item.actual_price,
                                        price: item.price),
                                    const AddToCartWidget(),
                                  ])),
                            ],
                          ),
                        ),
                      ),
                    ),
                  );
                },
                itemCount: CatalogModel.products?.length,
              ),
            )
          : const Center(
              child: CircularProgressIndicator(),
            ),
      drawer: MyDrawer(),
    );
  }

  void loadData() async {
    await Future.delayed(Duration(seconds: 5));
    final catalogJson =
        await rootBundle.loadString("assets/files/products.json");
    final decodedData = jsonDecode(catalogJson);
    final productData = decodedData["products"];
    CatalogModel.products = List.from(productData)
        .map<CatalogItem>((item) => CatalogItem.fromMap(item))
        .toList();
    setState(() {});
  }
}

PriceDetailsWidget.dart

class PriceDetailsWidget extends StatelessWidget {
  final String discount;
  final num price, actual_price;
  const PriceDetailsWidget({
    Key? key,
    required this.discount,
    required this.actual_price,
    required this.price,
  }) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Padding(
      padding: const EdgeInsets.only(top: 8.0),
      child: SizedBox(
        width: double.infinity,
        child: Row(
          crossAxisAlignment: CrossAxisAlignment.start,
          children: [
            Text("\${price}",
                textAlign: TextAlign.start,
                style: GoogleFonts.cabin(
                    textStyle: const TextStyle(
                        fontWeight: FontWeight.normal,
                        fontSize: 14.0,
                        decoration: TextDecoration.lineThrough,
                        decorationColor: Color(0xFF808080),
                        decorationThickness: 3.0,
                        color: Color(0xFF808080)))),
            Padding(
              padding: const EdgeInsets.only(left: 5.0),
              child: Text(
                "\${actual_price}",
                style: const TextStyle(
                  color: Color(MyTheme.primaryColor),
                  fontWeight: FontWeight.bold,
                  fontSize: 14.0,
                ),
              ),
            ),
            Padding(
              padding: const EdgeInsets.only(left: 5.0),
              child: Text(
                discount,
                style: const TextStyle(
                  color: Colors.red,
                  fontWeight: FontWeight.normal,
                  fontSize: 14.0,
                ),
              ),
            )
          ],
        ),
      ),
    );
  }
}

AddToCartWidget.dart

class AddToCartWidget extends StatelessWidget {
  const AddToCartWidget({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return ElevatedButton(
      onPressed: () {},
      style: ElevatedButton.styleFrom(elevation: 0.0, padding: EdgeInsets.zero),
      child: Row(
        mainAxisSize: MainAxisSize.max,
        mainAxisAlignment: MainAxisAlignment.center,
        crossAxisAlignment: CrossAxisAlignment.center,
        children: const [
          Icon(
            // <-- Icon
            CupertinoIcons.cart_fill,
            size: 24.0,
          ),
          SizedBox(
            width: 5,
          ),
          Text('Add to cart'), // <-- Text
        ],
      ),
    );
  }
}

CatalogModel & CatalogItem

class CatalogModel {
  static List<CatalogItem>? products;
}

class CatalogItem {
  final String id;
  final String name;
  final String desc;
  final num price;
  final num actual_price;
  final String discount;
  final String color;
  final String image;
  final String category;
  CatalogItem(
      {required this.id,
      required this.name,
      required this.desc,
      required this.price,
      required this.actual_price,
      required this.discount,
      required this.color,
      required this.image,
      required this.category});

  factory CatalogItem.fromMap(Map<String, dynamic> map) => CatalogItem(
      id: map["id"],
      name: map["name"],
      desc: map["desc"],
      price: map["price"],
      actual_price: map["actual_price"],
      discount: map["discount"],
      color: map["color"],
      image: map["image"],
      category: map["category"]);

  toMap() => {
        "id": id,
        "name": name,
        "desc": desc,
        "price": price,
        "color": color,
        "image": image,
      };
}

products.json this file I'm storing in the assets folder

{
    "products": [
        {
            "id": "prod001",
            "name": "iPhone 13 Pro",
            "desc": "Your iPhone will arrive.",
            "price": 1299,
            "actual_price": 999,
            "discount": "20% off",
            "color": "#536858",
            "image": "https://d2xamzlzrdbdbn.cloudfront.net/products/66d6056e-e588-4b03-a44b-74685197003622111313.jpg",
            "category": "Mobile"
        },
        {
            "id": "prod002",
            "name": "iPhone SE (PRODUCT) RED",
            "desc": "iPhone SE (PRODUCT) RED",
            "price": 429,
            "actual_price": 399,
            "discount": "15% off",
            "color": "#A7090A",
            "image": "https://www.neolight.in/wp-content/uploads/2022/01/iPhone_XR_red.jpg",
            "category": "Mobile"
        }
    ]
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

国际总奸 2025-02-14 09:46:00

TL,我在这里写。 HOT Reload正在通过向DART VM注入新的,更改的源代码来工作,DART VM仅在调试时起作用。因此,在您杀死该应用程序或关闭了调试会话后,VM降低了。唯一剩下的是您开始调试会话时首次安装的版本。这就是为什么当您在调试结束后重新打开它时,该应用仍显示旧错误版本。

如果要在不调试会话的情况下测试它,则可以

(1)构建版本版本

(2)只需关闭调试会话并再次启动调试会话,那么安装的应用程序应为最新版本

ref关于flutter flutter in flutter

TL, I write it here. Hot reload is working by injecting new, changed source code to the Dart VM which only works when debugging. So after you killed the app or closed the debug session, the VM is down. The only thing you left is the version you first installed when you start debug session. That's why when you reopen it after debug closed, the app is still showing the old error version.

If you want to test it without debug session, you may either

(1) build a release version

(2) just close the debug session and start the debug session again, then the app installed should be the latest version

Ref about hot reload in flutter

帅的被狗咬 2025-02-14 09:46:00

使用自定义SliverGridDelegate获取想要的东西

import 'package:flutter/rendering.dart';

class SliverGridDelegateWithFixedCrossAxisCountAndFixedHeight
extends SliverGridDelegate {

 const SliverGridDelegateWithFixedCrossAxisCountAndFixedHeight({
required this.crossAxisCount,
this.mainAxisSpacing = 0.0,
this.crossAxisSpacing = 0.0,
this.height = 56.0,
 })  : assert(crossAxisCount != null && crossAxisCount > 0),
    assert(mainAxisSpacing != null && mainAxisSpacing >= 0),
    assert(crossAxisSpacing != null && crossAxisSpacing >= 0),
    assert(height != null && height > 0);

final int crossAxisCount;
final double mainAxisSpacing;
final double crossAxisSpacing;
final double height;

  bool _debugAssertIsValid() {
  assert(crossAxisCount > 0);
  assert(mainAxisSpacing >= 0.0);
  assert(crossAxisSpacing >= 0.0);
  assert(height > 0.0);
  return true;
}

@override
SliverGridLayout getLayout(SliverConstraints constraints) {
assert(_debugAssertIsValid());
final double usableCrossAxisExtent =
    constraints.crossAxisExtent - crossAxisSpacing * (crossAxisCount - 1);
final double childCrossAxisExtent = usableCrossAxisExtent / crossAxisCount;
final double childMainAxisExtent = height;
return SliverGridRegularTileLayout(
  crossAxisCount: crossAxisCount,
  mainAxisStride: childMainAxisExtent + mainAxisSpacing,
  crossAxisStride: childCrossAxisExtent + crossAxisSpacing,
  childMainAxisExtent: childMainAxisExtent,
  childCrossAxisExtent: childCrossAxisExtent,
  reverseCrossAxis: axisDirectionIsReversed(constraints.crossAxisDirection),
);
 }

 @override
 bool shouldRelayout(
  SliverGridDelegateWithFixedCrossAxisCountAndFixedHeight oldDelegate) {
  return oldDelegate.crossAxisCount != crossAxisCount ||
    oldDelegate.mainAxisSpacing != mainAxisSpacing ||
    oldDelegate.crossAxisSpacing != crossAxisSpacing ||
    oldDelegate.height != height;
 }
 }

在此删除中,您可以通过GridView项目高度

use custom SliverGridDelegate for get what you want

import 'package:flutter/rendering.dart';

class SliverGridDelegateWithFixedCrossAxisCountAndFixedHeight
extends SliverGridDelegate {

 const SliverGridDelegateWithFixedCrossAxisCountAndFixedHeight({
required this.crossAxisCount,
this.mainAxisSpacing = 0.0,
this.crossAxisSpacing = 0.0,
this.height = 56.0,
 })  : assert(crossAxisCount != null && crossAxisCount > 0),
    assert(mainAxisSpacing != null && mainAxisSpacing >= 0),
    assert(crossAxisSpacing != null && crossAxisSpacing >= 0),
    assert(height != null && height > 0);

final int crossAxisCount;
final double mainAxisSpacing;
final double crossAxisSpacing;
final double height;

  bool _debugAssertIsValid() {
  assert(crossAxisCount > 0);
  assert(mainAxisSpacing >= 0.0);
  assert(crossAxisSpacing >= 0.0);
  assert(height > 0.0);
  return true;
}

@override
SliverGridLayout getLayout(SliverConstraints constraints) {
assert(_debugAssertIsValid());
final double usableCrossAxisExtent =
    constraints.crossAxisExtent - crossAxisSpacing * (crossAxisCount - 1);
final double childCrossAxisExtent = usableCrossAxisExtent / crossAxisCount;
final double childMainAxisExtent = height;
return SliverGridRegularTileLayout(
  crossAxisCount: crossAxisCount,
  mainAxisStride: childMainAxisExtent + mainAxisSpacing,
  crossAxisStride: childCrossAxisExtent + crossAxisSpacing,
  childMainAxisExtent: childMainAxisExtent,
  childCrossAxisExtent: childCrossAxisExtent,
  reverseCrossAxis: axisDirectionIsReversed(constraints.crossAxisDirection),
);
 }

 @override
 bool shouldRelayout(
  SliverGridDelegateWithFixedCrossAxisCountAndFixedHeight oldDelegate) {
  return oldDelegate.crossAxisCount != crossAxisCount ||
    oldDelegate.mainAxisSpacing != mainAxisSpacing ||
    oldDelegate.crossAxisSpacing != crossAxisSpacing ||
    oldDelegate.height != height;
 }
 }

in this delegrate you can pass gridview item height

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文