flutter 如何通过触摸方格来改变每个方格的颜色?

5lwkijsr  于 2023-05-23  发布在  Flutter
关注(0)|答案(1)|浏览(308)

更改正方形网格的正方形颜色

dart -我试图使一个页面与正方形网格所有与小方块。当触摸任何方块时,该方块的颜色应变为绿色。(触摸测试)有人能帮忙吗?
像这样:

import 'package:flutter/material.dart';
class MyPage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return LayoutBuilder(
      builder: (BuildContext context, BoxConstraints constraints) {
        double screenWidth = constraints.maxWidth;
        double screenHeight = constraints.maxHeight;
        
        double boxSize =
            screenWidth < screenHeight ? screenWidth / 10 : screenHeight / 10;
        int columns = (screenWidth / boxSize).floor();
        int rows = (screenHeight / boxSize).floor();
        int totalBoxes = columns * rows;

        return GestureDetector(
          onTapDown: (TapDownDetails details) {
            RenderBox box = context.findRenderObject() as RenderBox;
            Offset localPosition = box.globalToLocal(details.globalPosition);

            int tappedIndex = (localPosition.dx ~/ boxSize) +
                (localPosition.dy ~/ boxSize) * columns;

            if (tappedIndex >= 0 && tappedIndex < totalBoxes) {
              Navigator.push(
                context,
                MaterialPageRoute(
                  builder: (context) => DetailPage(),
                ),
              );
            }
          },
          child: GridView.count(
            crossAxisCount: columns,
            children: List.generate(
              totalBoxes,
              (index) => Container(
                decoration: BoxDecoration(
                  color: Colors.blue,
                  border: Border.all(color: Colors.white),
                ),
              ),
            ),
          ),
        );
      },
    );
  }
}

class DetailPage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Detail Page'),
      ),
      body: Center(
        child: Text('Detail Page Content'),
      ),
    );
  }
}

在这个程序中,通过触摸每个方块,它将返回到'DetailPage'我只是希望触摸方块的颜色改变。

m0rkklqb

m0rkklqb1#

如果你想在点击时改变颜色,你首先需要使用一个有状态的小部件,这样BoxDecorations的列表就可以在不刷新的情况下更新。
你上面的程序已经有了一种方法来找到已经被点击的盒子的索引(tappedIndex),所以我们可以使用它来检查这个tappedIndex是否等于每个盒子的索引(在List.generate()中找到),如果为真,就把盒子设置为绿色。
我们还需要记住在设置tappedIndex时使用setState(),以便网格视图会更新。
下面是最后的MyPage()代码。

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

  @override
  State<MyPage> createState() => _MyPageState();
}

class _MyPageState extends State<MyPage> {
  int? tappedIndex;
  @override
  Widget build(BuildContext context) {
    return LayoutBuilder(
      builder: (BuildContext context, BoxConstraints constraints) {
        double screenWidth = constraints.maxWidth;
        double screenHeight = constraints.maxHeight;

        double boxSize =
            screenWidth < screenHeight ? screenWidth / 10 : screenHeight / 10;
        int columns = (screenWidth / boxSize).floor();
        int rows = (screenHeight / boxSize).floor();
        int totalBoxes = columns * rows;

        return GestureDetector(
          onTapDown: (TapDownDetails details) {
            RenderBox box = context.findRenderObject() as RenderBox;
            Offset localPosition = box.globalToLocal(details.globalPosition);

            setState(() {
              tappedIndex = (localPosition.dx ~/ boxSize) +
                  (localPosition.dy ~/ boxSize) * columns;
            });
          },
          child: GridView.count(
            crossAxisCount: columns,
            children: List.generate(
              totalBoxes,
              (index) => Container(
                decoration: BoxDecoration(
                  color: index == tappedIndex ? Colors.green : Colors.blue,
                  border: Border.all(color: Colors.white),
                ),
              ),
            ),
          ),
        );
      },
    );
  }

以上只是基于你给出的例子实现颜色变化框的最简单方法,变化最少。还有其他方法可以达到同样的效果!
希望这有帮助!

相关问题