有没有办法在Flutter中动态创建网格视图?

cbeh67ev  于 2023-02-25  发布在  Flutter
关注(0)|答案(3)|浏览(165)

我尝试创建类似

的自定义外观网格
如果文本是从API动态获取的,有什么方法可以做到吗?

lyr7nygr

lyr7nygr1#

您可以使用flutter_staggered_grid_view包。
以下是本文档中创建自定义gridView的代码示例:

GridView.custom(
  gridDelegate: SliverQuiltedGridDelegate(
    crossAxisCount: 4,
    mainAxisSpacing: 4,
    crossAxisSpacing: 4,
    repeatPattern: QuiltedGridRepeatPattern.inverted,
    pattern: [
      QuiltedGridTile(2, 2),
      QuiltedGridTile(1, 1),
      QuiltedGridTile(1, 1),
      QuiltedGridTile(1, 2),
    ],
  ),
  childrenDelegate: SliverChildBuilderDelegate(
    (context, index) => Tile(index: index),
  ),
);

而结果是这样的:

有关详细信息,请点击以下链接:https://pub.dev/packages/flutter_staggered_grid_view

sycxhyv7

sycxhyv72#

你能试试这个吗?

import 'package:flutter/material.dart';

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

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

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
        title: 'Flutter Demo',
        theme: ThemeData(
          colorScheme: ColorScheme.fromSeed(seedColor: const Color(0xFF00B582)),
          chipTheme: ChipThemeData(
              disabledColor: Colors.white,
              selectedColor: const Color(0xFF00B582),
              showCheckmark: false,
              backgroundColor: Colors.white,
              elevation: 4,
              shape: RoundedRectangleBorder(
                borderRadius: BorderRadius.circular(8),
                side: BorderSide(color: Colors.grey.shade300),
              ),
              labelPadding: const EdgeInsets.all(8)),
          useMaterial3: false,
        ),
        home: const MyHomePage());
  }
}

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

  @override
  State<MyHomePage> createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  final _items = const <String>[
    "Otomotif",
    "E-commerce",
    "Edukasi",
    "Hiburan",
    "Keshehatan & Kecantikan",
    "Travel",
    "Olahraga",
    "Fashion",
    "Hadiah",
    "Makanan & Minuman",
    "Belanja"
  ];

  final _selected = <String>{};

  @override
  Widget build(BuildContext context) {
    final chipTheme = Theme.of(context).chipTheme;
    return SafeArea(
      child: Scaffold(
        body: Column(
          children: [
            const SizedBox(
              height: 20,
            ),
            Center(
              child: Padding(
                padding: const EdgeInsets.all(5),
                child: Wrap(
                  alignment: WrapAlignment.spaceEvenly,
                  // crossAxisAlignment: WrapCrossAlignment.center,
                  // runAlignment: WrapAlignment.spaceBetween,
                  spacing: 10,
                  runSpacing: 10,
                  clipBehavior: Clip.antiAlias,
                  children: _items.map(
                    (item) {
                      final isSelected = _selected.contains(item);
                      return FilterChip(
                        selected: isSelected,
                        elevation: isSelected ? chipTheme.elevation : 0,
                        shape: isSelected
                            ? RoundedRectangleBorder(
                                side:
                                    const BorderSide(color: Colors.transparent),
                                borderRadius: BorderRadius.circular(8),
                              )
                            : chipTheme.shape,
                        labelStyle: isSelected
                            ? const TextStyle(color: Colors.white, fontSize: 18)
                            : const TextStyle(fontSize: 18),
                        onSelected: (bool value) {
                          if (value) {
                            _selected.add(item);
                          } else {
                            _selected.remove(item);
                          }
                          setState(() {});
                        },
                        label: Text(item),
                      );
                    },
                  ).toList(),
                ),
              ),
            )
          ],
        ),
      ),
    );
  }
}

输出:

iih3973s

iih3973s3#

尝试FlexList包,我能够得到类似的结果,你想要的:

class FlexListTest extends StatelessWidget {
  const FlexListTest({super.key, this.words = const []});

  final List<String> words;
  final textStyle = const TextStyle(fontSize: 20);

  @override
  Widget build(BuildContext context) {
    return FlexList(
      horizontalSpacing: 5,
      verticalSpacing: 10,
      children: words.map((word) => textBox(word)).toList(),
    );
  }

  Widget textBox(String word) {
    return Container(
      padding: const EdgeInsets.all(16.0),
      margin: const EdgeInsets.all(8.0),
      decoration: BoxDecoration(
        color: Random.secure().nextBool() ? Colors.white : Colors.tealAccent,
        borderRadius: BorderRadius.circular(10),
        border: Border.all(
          color: Colors.grey,
        ),
      ),
      child: Text(
        word,
        textAlign: TextAlign.center,
        style: textStyle,
      ),
    );
  }
}

然后在要渲染的位置调用它:

const FlexListTest(words: ['Otomotif', 'E-commerce', 'Edukasi', 'Hiburan', 'Kesehatan & Kecantikan', 'Travel', 'Olahraga', 'Fashion', 'Hadiah', 'Makanan & Minuman', 'Belanja']),

模拟器上的输出:

当然,您必须添加API调用的结果,以及您想对瓷砖做什么的逻辑等,我只是在我的代码中为这个测试添加了一个随机颜色。:)
链接到pub.dev软件包:https://pub.dev/packages/flex_list

相关问题