flutter 在列表视图中抖动错误的图像大小

noj0wjuj  于 2022-12-05  发布在  Flutter
关注(0)|答案(4)|浏览(151)

我已经创建了一个列表视图与图像在Flutter。它的工作,但图像是错误的大小。它看起来像这样:

但我想要的是:

这是我正在使用的代码:

SizedBox(
                      height: 300,
                      child: ListView.builder(
                        shrinkWrap: true,
                        scrollDirection: Axis.horizontal,
                        itemBuilder: (BuildContext ctx, int index) {
                          return SizedBox(
                              width: MediaQuery.of(context).size.width * 0.5,
                              child: Card(
                                child: ClipRRect(
                                  borderRadius: BorderRadius.circular(10),
                                  child: Image.file(
                                    File(_imageFileListM[index].path),
                                    fit: BoxFit.fitWidth,
                                  ),
                                ),
                                margin: const EdgeInsets.all(10),
                                shape: RoundedRectangleBorder(
                                  borderRadius: BorderRadius.circular(20.0),
                                ),
                              ));
                        },
                        itemCount: _imageFileListM.length,
                      ))

我做错了什么?

scyqe7ek

scyqe7ek1#

试试这个:

SizedBox(
          height: 300,
          child: ListView.builder(
            shrinkWrap: true,
            scrollDirection: Axis.horizontal,
            itemBuilder: (BuildContext ctx, int index) {
              return SizedBox(
                  width: MediaQuery.of(context).size.width * 0.5,
                  child: Card(
                    elevation: 0,
                    color: Colors.transparent,
                    surfaceTintColor: Colors.transparent,
                    child: Align(
                      alignment: Alignment.center,
                      child: Container(
                        clipBehavior: Clip.antiAlias,
                        decoration: BoxDecoration(
                          color: Colors.transparent,
                          borderRadius: BorderRadius.circular(10),
                        ),
                        child: Image.file(
                          File(_imageFileListM[index].path),
                          fit: BoxFit.contain,
                        ),
                      ),
                    ),
                    margin: const EdgeInsets.all(10),
                    shape: RoundedRectangleBorder(
                      borderRadius: BorderRadius.circular(20.0),
                    ),
                  ));
            },
            itemCount: _imageFileListM.length,
          )),

htrmnn0y

htrmnn0y2#

使用容器小部件类似于以下框装饰属性可能会对您有所帮助
容器(高度:200.h,宽度:双倍。无限,装饰:框装饰(图片:装饰图像(图像:AssetImage(“输入您的路径”)),颜色:基础颜色2,边界半径:仅限边界半径(左下角:圆形半径(20.r),右下角:圆形半径(20.r)),
),

fnx2tebb

fnx2tebb3#

只需使用FittedBox Package 列表元素,如下所示:

SizedBox(
  height: 300,
  child: ListView.builder(
    shrinkWrap: true,
    scrollDirection: Axis.horizontal,
    itemBuilder: (BuildContext ctx, int index) {
      return SizedBox(
          width: MediaQuery.of(context).size.width * 0.5,
          child: FittedBox(
            child: Card(
              child: ClipRRect(
                borderRadius: BorderRadius.circular(20),
                child: Image.file(
                  File(_imageFileListM[index].path),
                  fit: BoxFit.fitWidth,
                ),
              ),
              margin: const EdgeInsets.all(10),
              shape: RoundedRectangleBorder(
                borderRadius: BorderRadius.circular(20.0),
              ),
            ),
          ));
    },
    itemCount: _imageFileListM.length,
  )))
q3qa4bjr

q3qa4bjr4#

实现此目的的简单方法是使用Stack和position。
Stack允许小部件彼此重叠。Positioned允许您在堆栈中的特定位置呈现其子部件。
堆栈非常类似于一个列,但是小部件是在彼此的顶部呈现的,因此您需要指定它们应该如何呈现。
这将是您的主要图像小部件:
1.图像被包裹在一个扩展大小的框中以覆盖整个空间。

  1. positioned设置为bottom 0将把小部件粘在底部。left和right被指定为0,这样小部件也会水平展开。
class ImageWidget extends StatelessWidget {
  final String url;
  const ImageWidget({super.key, required this.url});

  @override
  Widget build(BuildContext context) {
    return ClipRRect(
      borderRadius: BorderRadius.circular(16),
      child: Stack(
        children: [
          SizedBox.expand(
            child: Image.network(
              url,
              fit: BoxFit.contain,
            ),
          ),
          const Positioned(
            left: 0,
            right: 0,
            bottom: 0,
            child: ImageChildWidget(),
          ),
        ],
      ),
    );
  }
}

这是最下面的部分。你可以用任何你喜欢的东西来代替它。

class ImageChildWidget extends StatelessWidget {
  const ImageChildWidget({super.key});

  @override
  Widget build(BuildContext context) {
    return const ColoredBox(
      color: Color.fromARGB(155, 0, 0, 0),
      child: Padding(
        padding: EdgeInsets.all(8),
        child: Text(
          'Some Long Text',
          style: TextStyle(
            color: Colors.white,
            fontSize: 16,
          ),
        ),
      ),
    );
  }
}

您也有一个网格视图,使用gridDelegate很容易

  • 交叉轴计数:2表示每行需要2个元素
  • 主轴间距:16表示您希望垂直填充为16
  • 交叉轴间距:16表示您希望水平填充为16
class GridExample extends StatefulWidget {
  const GridExample({super.key});

  @override
  State<GridExample> createState() => GridExampleState();
}

class GridExampleState extends State<GridExample> {
  // Generate a random list of images
  List<String> urls = List.generate(
    10,
    (_) {
      int random = Random().nextInt(500) + 250; // 250-500
      return 'https://picsum.photos/$random/$random';
    },
  );

  @override
  Widget build(BuildContext context) {
    return GridView.builder(
      key: widget.key,
      itemCount: urls.length,
      padding: const EdgeInsets.all(16),
      gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(
        crossAxisCount: 2,
        mainAxisSpacing: 16,
        crossAxisSpacing: 16,
      ),
      itemBuilder: (context, index) {
        return ImageWidget(
          key: ValueKey(urls[index]),
          url: urls[index],
        );
      },
    );
  }
}

完整的代码示例。

import 'dart:math';

import 'package:flutter/material.dart';

void main() {
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return const MaterialApp(
      debugShowCheckedModeBanner: false,
      home: Scaffold(
        body: Center(
          child: GridExample(
            key: ValueKey('grid'),
          ),
        ),
      ),
    );
  }
}

class GridExample extends StatefulWidget {
  const GridExample({super.key});

  @override
  State<GridExample> createState() => GridExampleState();
}

class GridExampleState extends State<GridExample> {
  // Generate a random list of images
  List<String> urls = List.generate(
    10,
    (_) {
      int random = Random().nextInt(500) + 250; // 250-500
      return 'https://picsum.photos/$random/$random';
    },
  );

  @override
  Widget build(BuildContext context) {
    return GridView.builder(
      key: widget.key,
      itemCount: urls.length,
      padding: const EdgeInsets.all(16),
      gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(
        crossAxisCount: 2,
        mainAxisSpacing: 16,
        crossAxisSpacing: 16,
      ),
      itemBuilder: (context, index) {
        return ImageWidget(
          key: ValueKey(urls[index]),
          url: urls[index],
        );
      },
    );
  }
}

class ImageWidget extends StatelessWidget {
  final String url;
  const ImageWidget({super.key, required this.url});

  @override
  Widget build(BuildContext context) {
    return ClipRRect(
      borderRadius: BorderRadius.circular(16),
      child: Stack(
        children: [
          SizedBox.expand(
            child: Image.network(
              url,
              fit: BoxFit.contain,
            ),
          ),
          const Positioned(
            left: 0,
            right: 0,
            bottom: 0,
            child: ImageChildWidget(),
          ),
        ],
      ),
    );
  }
}

class ImageChildWidget extends StatelessWidget {
  const ImageChildWidget({super.key});

  @override
  Widget build(BuildContext context) {
    return const ColoredBox(
      color: Color.fromARGB(155, 0, 0, 0),
      child: Padding(
        padding: EdgeInsets.all(8),
        child: Text(
          'Some Long Text',
          style: TextStyle(
            color: Colors.white,
            fontSize: 16,
          ),
        ),
      ),
    );
  }
}

最终结果:

相关问题