Flutter,交错 flutter_staggered_grid_view 使每个图块都可点击而不破坏布局

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

这里是新开发人员,需要一些专业知识。我正在尝试创建一个自定义的交错网格视图,该视图还允许每个图块可点击并进入不同的页面。

我尝试过使用墨水池,但我似乎无法对每个单独的瓷砖都这样做。然后就进入了手势检测器。我可以将整个网格视图包装为可使用手势检测器点击,但这使得整个网格可点击,并且全部进入一个页面。

知道如何使每个单独的图块可点击,然后将其链接到另一个页面吗?当我尝试为每个人做这件事时,它完全破坏了布局。使每个图块大小相同。然后我尝试使每个图块尺寸可定制,但这不起作用。我尝试使用 chatGPT 使其全部可定制,但它无法完全实现这一目标。忽略顶部图像资源。

感谢任何和所有帮助。即使我需要使用其他东西来构建我想做的事情。查看其当前状态的示例图像。

actual state of app now, screenshot of phone

在 Windows 上使用 Visual Studio

依赖关系: 扑: sdk:颤振

cupertino_icons:^1.0.2 谷歌字体:^5.1.0 flutter_staggered_grid_view:^0.7.0

我尝试使用聊天 GPT 要求它确实使每个图块可点击,保持原始图块大小,每个图块指向不同的页面,但我不断浏览网络和更长的代码库,它最终无法满足我的需要它要做。

dependencies:
  flutter:
    sdk: flutter

  cupertino_icons: ^1.0.2
  google_fonts: ^5.1.0
  flutter_staggered_grid_view: ^0.7.0

import 'package:flutter/material.dart';
import 'package:flutter_staggered_grid_view/flutter_staggered_grid_view.dart';
import 'package:google_fonts/google_fonts.dart';

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

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('new app'),
        centerTitle: true,
      ),
      body: Column(
        children: [
          Image.asset(
            'assets/images/bannerbig.png',
            fit: BoxFit.cover,
            width: double.infinity,
          ),
          Expanded(
            child: SingleChildScrollView(
              child: GestureDetector(
                // Wraped the StaggeredGrid with GestureDetector
                onTap: () {
                  Navigator.push(
                    context,
                    MaterialPageRoute(
                      builder: (context) => PointsPage(),
                    ),
                  );
                },
                child: StaggeredGrid.count(
                  crossAxisCount: 4,
                  mainAxisSpacing: 4,
                  crossAxisSpacing: 4,
                  children: const [
                    StaggeredGridTile.count(
                      crossAxisCellCount: 2,
                      mainAxisCellCount: 2,
                      child: Tile(
                        index: 0,
                        color: Color.fromARGB(255, 255, 255, 255),
                        customText: '50\npoints',
                        fontSize: 30,
                      ),
                    ),
                    StaggeredGridTile.count(
                      crossAxisCellCount: 2,
                      mainAxisCellCount: 1,
                      child: Tile(
                        index: 1,
                        color: Color.fromARGB(255, 129, 173, 180),
                        customText: 'Leagues',
                      ),
                    ),
                    StaggeredGridTile.count(
                      crossAxisCellCount: 1,
                      mainAxisCellCount: 1,
                      child: Tile(
                        index: 2,
                        color: Colors.green,
                        customText: 'Stats',
                      ),
                    ),
                    StaggeredGridTile.count(
                      crossAxisCellCount: 1,
                      mainAxisCellCount: 1,
                      child: Tile(
                        index: 3,
                        color: Colors.red,
                        customText: 'Custom Text for Tile 3',
                      ),
                    ),
                    StaggeredGridTile.count(
                      crossAxisCellCount: 4,
                      mainAxisCellCount: 2,
                      child: Tile(
                        index: 4,
                        color: Colors.purple,
                        customText: 'Custom Text for Tile 4',
                      ),
                    ),
                  ],
                ),
              ),
            ),
          ),
        ],
      ),
    );
  }
}

class Tile extends StatelessWidget {
  final int index;
  final Color color;
  final double fontSize;
  final String? customText;

  const Tile({
    required this.index,
    required this.color,
    this.fontSize = 15, // Provide a default value for fontSize.
    this.customText,
    Key? key,
  }) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Card(
      color: color,
      child: Center(
        child: Text(
          customText ?? 'Tile $index',
          style: GoogleFonts.openSans(
            fontSize: fontSize,
            color: const Color.fromARGB(255, 0, 0, 0),
          ),
        ),
      ),
    );
  }
}

// Placeholder page for demonstration purposes.
class PointsPage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text('Points Page')),
      body: Center(child: Text('Points Page Content')),
    );
  }
}

// chat gpt tried it like this. 

import 'package:flutter/material.dart';
import 'package:flutter_staggered_grid_view/flutter_staggered_grid_view.dart';
import 'package:google_fonts/google_fonts.dart';

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

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('new app'),
        centerTitle: true,
      ),
      body: Column(
        children: [
          Image.asset(
            'assets/images/bannerbig.png',
            fit: BoxFit.cover,
            width: double.infinity,
          ),
          Expanded(
            child: SingleChildScrollView(
              child: GestureDetector(
                // Wrap the StaggeredGrid with GestureDetector
                onTap: () {
                  Navigator.push(
                    context,
                    MaterialPageRoute(
                      builder: (context) => PointsPage(),
                    ),
                  );
                },
                child: StaggeredGridView.countBuilder(
                  crossAxisCount: 4,
                  itemCount: 4,
                  mainAxisSpacing: 4,
                  crossAxisSpacing: 4,
                  staggeredTileBuilder: (index) => StaggeredTile.fit(2),
                  itemBuilder: (context, index) {
                    return GestureDetector(
                      onTap: () {
                        switch (index) {
                          case 0:
                            Navigator.pushNamed(context, '/tile1');
                            break;
                          case 1:
                            Navigator.pushNamed(context, '/tile2');
                            break;
                          case 2:
                            Navigator.pushNamed(context, '/tile3');
                            break;
                          case 3:
                            Navigator.pushNamed(context, '/tile4');
                            break;
                        }
                      },
                      child: Tile(
                        index: index,
                        color: index == 0
                            ? Color.fromARGB(255, 255, 255, 255)
                            : index == 1
                                ? Color.fromARGB(255, 129, 173, 180)
                                : index == 2
                                    ? Colors.green
                                    : Colors.red,
                        customText: index == 0 ? '50\npoints' : 'Custom Text for Tile $index',
                        fontSize: index == 0 ? 30 : 15,
                      ),
                    );
                  },
                ),
              ),
            ),
          ),
        ],
      ),
    );
  }
}

class Tile extends StatelessWidget {
  final int index;
  final Color color;
  final double fontSize;
  final String? customText;

  const Tile({
    required this.index,
    required this.color,
    this.fontSize = 15, // Provide a default value for fontSize.
    this.customText,
    Key? key,
  }) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Card(
      color: color,
      child: Center(
        child: Text(
          customText ?? 'Tile $index',
          style: GoogleFonts.openSans(
            fontSize: fontSize,
            color: const Color.fromARGB(255, 0, 0, 0),
          ),
        ),
      ),
    );
  }
}

// Placeholder page for demonstration purposes.
class PointsPage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text('Points Page')),
      body: Center(child: Text('Points Page Content')),
    );
  }
}

void main() {
  runApp(MaterialApp(
    home: FantasyHome(),
    routes: {
      // Define routes for individual pages
      '/tile1': (context) => TilePage(tile: tiles[0]),
      '/tile2': (context) => TilePage(tile: tiles[1]),
      '/tile3': (context) => TilePage(tile: tiles[2]),
      '/tile4': (context) => TilePage(tile: tiles[3]),
    },
  ));
}

// Sample data for the tiles
final List<TileModel> tiles = [
  TileModel(title: 'Tile 1', description: 'Description for Tile 1'),
  TileModel(title: 'Tile 2', description: 'Description for Tile 2'),
  TileModel(title: 'Tile 3', description: 'Description for Tile 3'),
  TileModel(title: 'Tile 4', description: 'Description for Tile 4'),
];

class TileModel {
  final String title;
  final String description;

  TileModel({required this.title, required this.description});
}

class TilePage extends StatelessWidget {
  final TileModel tile;

  TilePage({required this.tile});

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text(tile.title)),
      body: Center(
        child: Text(tile.description),
      ),
    );
  }
}


flutter dart flutter-dependencies flutter-animation flutter-gridview
1个回答
0
投票

在您的

Tile
小部件中,用
GestureDetector
InkWell
包裹卡片,并设置 onTap 处理程序以在点击时执行您想要的操作。

GestureDetector
InkWell
都是“不可见”小部件,不会更改应用程序的布局或外观。如果您希望点击时材料颜色飞溅,请使用 InkWell,否则请使用 GestureDetector。

© www.soinside.com 2019 - 2024. All rights reserved.