如何让AppBar图标触发渲染?

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

我想我的应用程序设计错了。我是新手,因为以前使用其他语言(特别是C#和JavaScript)而感到困惑。

我有一个应用程序,目前包含一个3 x 3 GridView的9彩色圆形瓷砖,名为Tiled_Surface。每个磁贴都分配了以下onTap处理程序:

  void on_tile_tapped(int index) {
    setState(() {
      tile_tapped = index;
    });
  } // on_tile_tapped

其中index具有[0..8]范围内的任意值。无论何时敲击图块,图块的颜色都会变为较亮的值(实际上是图块颜色的“强调颜色”)。所有这些工作文件。

AppBar包含一个标题(“Tiled Surface Demo”)和两个由两个IconButtons(Icons.swap_horiz和Icons.replay)组成的动作。当点击交换图标时,旨在将图块颜色混洗成新的随机顺序。当点击重播图标时,图块颜色将恢复为原始顺序。当点击两个AppBar图标时,在点击一个图块之前,显示器没有明显的变化。然后,显示AppBar点击所做的更改。

这不是理想的效果。我的问题是如何在点击AppBar图标时渲染Tiled_Surface。

该应用程序的代码如下。谢谢你的想法。

// ignore_for_file: camel_case_types
// ignore_for_file: constant_identifier_names
// ignore_for_file: non_constant_identifier_names

import 'package:flutter/material.dart';
import 'dart:math';

const int NUMBER_TILES = 9;
final int cross_axis_count = (sqrt (NUMBER_TILES)).toInt();

final double cross_axis_spacing = 4.0;
final double main_axis_spacing = cross_axis_spacing;

List<int> indices = [ 0, 1, 2, 3, 4, 5, 6, 7, 8 ];

List normal_colors = [
  Colors.red,
  Colors.orange,
  Colors.yellow,
  Colors.green,
  Colors.blue,
  Colors.purple,
  Colors.amber,
  Colors.cyan,
  Colors.indigo,
]; // normal_colors

List bright_colors = [
  Colors.pinkAccent,
  Colors.orangeAccent,
  Colors.yellowAccent,
  Colors.lightGreenAccent,
  Colors.blue.shade200,
  Colors.purpleAccent,
  Colors.amberAccent,
  Colors.cyanAccent,
  Colors.indigoAccent,
]; // bright_colors

void reinitialize_tiles() {
  indices.clear();
  for (int i = 0; (i < NUMBER_TILES); i++) {
    indices.add(i);
  }
} // reinitialize_tiles

void randomize_tiles() {
  var random = new Random();

  indices.clear();
  for (int i = 0; (i < NUMBER_TILES); i++) {
    var varient = random.nextInt(9);

    if (indices.length > 0) {
      while (indices.contains(varient)) {
        varient = random.nextInt(9);
      }
    }
    indices.add(varient);
  }
} // randomize_tiles

void main() => runApp(new MyApp());

class Tiled_Surface extends StatefulWidget {
  Tiled_Surface({Key key}) : super(key: key);

  @override // Tiled_Surface
  Tiled_Surface_State createState() => Tiled_Surface_State();
}

class Tiled_Surface_State extends State<Tiled_Surface> {
  List<GridTile> grid_tiles = <GridTile>[];
  int tile_tapped = -1;

  void on_tile_tapped(int index) {
    setState(() {
      tile_tapped = index;
    });
  } // on_tile_tapped

  GridTile new_surface_tile(Color tile_color, int index) {
    GridTile tile = GridTile(
      child: GestureDetector(
        onTap: () => on_tile_tapped(index),
        child: Container(
          decoration: BoxDecoration(
            color: tile_color,
            shape: BoxShape.circle,
          ),
        ),
      )
    );
  return (tile);
  } // new_surface_tile

  List<GridTile> create_surface_tiles() {
    grid_tiles = new List<GridTile>();

    for (int i = 0; (i < NUMBER_TILES); i++) {
      Color tile_color = ( tile_tapped == i ) ?
                           bright_colors[indices[i]] :
                           normal_colors[indices[i]];

      grid_tiles.add(new_surface_tile(tile_color, i));
    }
    return (grid_tiles);
  } // create_surface_tiles

  @override // Tiled_Surface_State
  Widget build(BuildContext context) {
    return GridView.count(
      shrinkWrap: true,
      crossAxisCount: cross_axis_count,
      childAspectRatio: 1.0,
      padding: const EdgeInsets.all(4.0),
      mainAxisSpacing: main_axis_spacing,
      crossAxisSpacing: cross_axis_spacing,
      children: create_surface_tiles(),
    );
  }
} // class Tiled_Surface_State

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Tiled Surface Demo',
      home: Scaffold(
        appBar: AppBar(
          title: Text('Tiled Surface Demo'),
          actions: <Widget>[
            IconButton(
              icon: Icon(Icons.swap_horiz),
              onPressed: () {
                randomize_tiles();
              },
            ),
            IconButton(
              icon: Icon(Icons.replay),
              onPressed: () {
                reinitialize_tiles();
              },
            )
          ]
        ),
        body: Column(
          children: [
            Tiled_Surface(),
          ],
        ),
      ),
    );
  }
}
dart flutter
1个回答
0
投票

问题:颤动小部件(有状态)仅对状态变量作出反应。不适用于全球和本地。在您的示例中,indices是一个全局变量。

我更新了代码

  • indices移动到MyApp中 可变的全局变量并不好 我们希望我们的MyApp能够反映指数的变化
  • MyApp开始举行state改变它作为StatefulWidget
  • randomize_tilesreinitialize_tiles移动到_MyAppState并在更换setState时添加了indices,以便小部件将获得re-rendered
  • 由于Tiled_Surface也需要索引,injecting(传递)它们在构造函数中。

请看一看

import 'package:flutter/material.dart';
import 'dart:math';

const int NUMBER_TILES = 9;
final int cross_axis_count = (sqrt(NUMBER_TILES)).toInt();

final double cross_axis_spacing = 4.0;
final double main_axis_spacing = cross_axis_spacing;

List normal_colors = [
  Colors.red,
  Colors.orange,
  Colors.yellow,
  Colors.green,
  Colors.blue,
  Colors.purple,
  Colors.amber,
  Colors.cyan,
  Colors.indigo,
]; // normal_colors

List bright_colors = [
  Colors.pinkAccent,
  Colors.orangeAccent,
  Colors.yellowAccent,
  Colors.lightGreenAccent,
  Colors.blue.shade200,
  Colors.purpleAccent,
  Colors.amberAccent,
  Colors.cyanAccent,
  Colors.indigoAccent,
]; // bright_colors

void main() => runApp(new MyApp());

class Tiled_Surface extends StatefulWidget {
  List<int> indices;

  Tiled_Surface(this.indices, {Key key}) : super(key: key);

  @override // Tiled_Surface
  Tiled_Surface_State createState() => Tiled_Surface_State(indices);
}

class Tiled_Surface_State extends State<Tiled_Surface> {
  List<GridTile> grid_tiles = <GridTile>[];
  int tile_tapped = -1;
  List<int> indices;

  Tiled_Surface_State(this.indices);

  void on_tile_tapped(int index) {
    setState(() {
      tile_tapped = index;
    });
  } // on_tile_tapped

  GridTile new_surface_tile(Color tile_color, int index) {
    GridTile tile = GridTile(
        child: GestureDetector(
      onTap: () => on_tile_tapped(index),
      child: Container(
        decoration: BoxDecoration(
          color: tile_color,
          shape: BoxShape.circle,
        ),
      ),
    ));
    return (tile);
  } // new_surface_tile

  List<GridTile> create_surface_tiles() {
    grid_tiles = new List<GridTile>();

    for (int i = 0; (i < NUMBER_TILES); i++) {
      Color tile_color = (tile_tapped == i)
          ? bright_colors[indices[i]]
          : normal_colors[indices[i]];

      grid_tiles.add(new_surface_tile(tile_color, i));
    }
    return (grid_tiles);
  } // create_surface_tiles

  @override // Tiled_Surface_State
  Widget build(BuildContext context) {
    return GridView.count(
      shrinkWrap: true,
      crossAxisCount: cross_axis_count,
      childAspectRatio: 1.0,
      padding: const EdgeInsets.all(4.0),
      mainAxisSpacing: main_axis_spacing,
      crossAxisSpacing: cross_axis_spacing,
      children: create_surface_tiles(),
    );
  }
} // class Tiled_Surface_State

class MyApp extends StatefulWidget {
  @override
  State<StatefulWidget> createState() {
    return new _MyAppState();
  }
}

class _MyAppState extends State<MyApp> {
  List<int> indices = [0, 1, 2, 3, 4, 5, 6, 7, 8];

  void randomize_tiles() {
    var random = new Random();

    indices.clear();
    for (int i = 0; (i < NUMBER_TILES); i++) {
      var varient = random.nextInt(9);

      if (indices.length > 0) {
        while (indices.contains(varient)) {
          varient = random.nextInt(9);
        }
      }
      indices.add(varient);
    }
    setState(() {});
  }

  void reinitialize_tiles() {
    indices.clear();
    for (int i = 0; (i < NUMBER_TILES); i++) {
      indices.add(i);
    }
    setState(() {});
  }

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Tiled Surface Demo',
      home: Scaffold(
        appBar: AppBar(title: Text('Tiled Surface Demo'), actions: <Widget>[
          IconButton(
            icon: Icon(Icons.swap_horiz),
            onPressed: () {
              randomize_tiles();
            },
          ),
          IconButton(
            icon: Icon(Icons.replay),
            onPressed: () {
              reinitialize_tiles();
            },
          )
        ]),
        body: Column(
          children: [
            Tiled_Surface(indices),
          ],
        ),
      ),
    );
  }
}
© www.soinside.com 2019 - 2024. All rights reserved.