如何使网格视图项目屏幕宽度颤动

How to make grid view item screen width Flutter

如何创建一个网格视图,其中每个项目都位于屏幕的中心并且宽度适合给定的屏幕?无论我做什么,在水平滚动中,我的项目都很大,我无法将它们缩放到屏幕中央。我想在每个屏幕上滚动一个项目。 我一直在尝试 ListView、Padding、Wrap、Align。

我有:

我想要的:

我的代码:

class NewestView extends StatelessWidget {
  const NewestView({Key? key, required this.state}) : super(key: key);

  final TestState state;

  @override
  Widget build(context) {
    return BlocBuilder<NavigationCubit, NavigationState>(
        builder: (context, state) {
      return Builder(builder: (context) {
        return  GridView.count(
          padding: const EdgeInsets.all(25),
          crossAxisCount: 1,
          children: _generateGrid(15, context),
          scrollDirection: Axis.horizontal,
          shrinkWrap: true,
        );
      });
    });
  }

  List<Widget> _generateGrid(int number, BuildContext context) {
    List<Widget> gridResult = [];
    for (int i = 0; i < number; i++) {
      IconData genIcon = RandomIconData.randomIcon();
      Image image = Image(image: Picsum().randomPic().image);
      gridResult.add(
        Builder(
          builder: (BuildContext context) => InkWell(
            borderRadius: BorderRadius.circular(50),
            onTap: () {
              _onTapAction(context, genIcon, image);
            },
            child: Card(
              child: Column(
                children: [
                  Flexible(
                    flex: 1
                    child: Center(
                      // color: Colors.deepOrangeAccent,
                      child: Text(
                        'Test',
                        style: Theme.of(context)
                            .textTheme
                            .caption
                            ?.copyWith(fontWeight: FontWeight.bold),
                      ),
                    ),
                  ),
                  Flexible(
                    flex: 4,
                    child: Builder(builder: (context) {
                      return Container(
                        color: Colors.transparent,
                        child: image,
                      );
                    }),
                  ),
                  Flexible(
                    flex: 2,
                    child: Container(
                      color: Colors.transparent,
                      child: const Icon(
                        Icons.monetization_on,
                        color: Colors.amber,
                      ),
                    ),
                  )
                ],
              ),
            ),
          ),
        ),
      );
    }
    return gridResult;
  }

您本质上是想制作一个 ListView。但是您使用 crossAxisCount = 1 的 GridView。除非您另有说明,否则 GridView 子项的纵横比为 1:1。因此,将 GridView 更改为 ListView。使用 MediaQuery 为 Card 提供一个相对于视口大小的子级,这样它就不会被挤压。

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

  // final TestState state;

  @override
  Widget build(context) {
    return ListView(
      children: _generateGrid(15, context),
      scrollDirection: Axis.horizontal,
      shrinkWrap: true,
    );
  }

  List<Widget> _generateGrid(int number, BuildContext context) {
    List<Widget> gridResult = [];
    for (int i = 0; i < number; i++) {
      IconData genIcon = Icons.ac_unit_outlined;
      Image image = Image.network('https://via.placeholder.com/450x800.png');
      gridResult.add(
        Card(
          child: SizedBox(
            width: MediaQuery.of(context).size.width,
            child: Column(
              children: [
                Flexible(
                  flex: 1,
                  child: Center(
                    // color: Colors.deepOrangeAccent,
                    child: Text(
                      'Test',
                      style: Theme.of(context)
                          .textTheme
                          .caption
                          ?.copyWith(fontWeight: FontWeight.bold),
                    ),
                  ),
                ),
                Flexible(
                  flex: 4,
                  child: Builder(builder: (context) {
                    return Container(
                      color: Colors.transparent,
                      child: image,
                    );
                  }),
                ),
                Flexible(
                  flex: 2,
                  child: Container(
                    color: Colors.transparent,
                    child: const Icon(
                      Icons.monetization_on,
                      color: Colors.amber,
                    ),
                  ),
                )
              ],
            ),
          ),
        ),
      );
    }
    return gridResult;
  }
}