dart - 在点击图标时呈现屏幕

标签 dart flutter

我仍然无法通过点击图标来重绘应用程序屏幕。我使用 GitHub 上的 Vanilla 项目作为指南。我显然错过了什么!

该应用在 GridView 中显示 9 个圆圈。 main.dart 包含 runApp(CirclesApp());。 CirclesApp(在 circlesapp.dart 中)包含通过调用 Circles(在 circles.dart 中)显示 9 个圆圈的代码。 CirclesApp 创建将传递给 Circles 的 AppState(在 appstate.dart 中)。 CirclesApp 包含带有图标的 AppBar,点击该图标会调用函数 flash_all_tiles()。该函数遍历 9 个图 block ,将 flash_tile 值设置为当前图 block 的索引并延迟 500 毫秒。计时器超时函数将 flash_tile 值重置为 -1。

点击 AppBar Icons.replay 图标后,我希望看到的是每个圆圈依次闪烁。我确实看到主页栏按钮发生了变化,但每个圆圈的亮度没有变化。每个圆圈的颜色由 create_circle_tiles 函数(在 circles.dart 中)通过将当前图 block 索引与 widget.appState.flash_tile 进行比较来确定。

应用程序的代码如下。不包括文件 circle_colors.dart、constants.dart 和 strings.dart。

主 Dart :

// 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 'circlesapp.dart';

void main() => runApp(CirclesApp());

circlesapp.dart:

// 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:async';

import 'appstate.dart';
import 'constants.dart';
import 'circles.dart';
import 'strings.dart';

class CirclesApp extends StatefulWidget {

  CirclesApp();

  @override
  State<StatefulWidget> createState() {return CirclesAppState();
  }
} // class CirclesApp

class CirclesAppState extends State<CirclesApp> {
  AppState appState = AppState();

  @override
  void initState() {
    super.initState();

    setState(() {
      appState = AppState(flash_tile: -1);
    });
  } // initState()

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: Strings.appTitle,
      home: Scaffold(
        appBar: AppBar(
          title: Text(Strings.appTitle),
          actions: <Widget>[
            IconButton(
              icon: Icon(Icons.replay),
              onPressed: () => flash_all_tiles(),
            )
          ]
        ),
        body: Column(
          children: [
            Circles (
              appState: appState,
            ),
          ],
        ),
      ),
    );
  }

  Timer start_flash_timeout(Duration duration) {
    return new Timer(duration, on_flash_timeout);
  } // start_flash_timeout

  void on_flash_timeout() {
    setState((){
      appState.flash_tile  = -1;
    });
  } // on_flash_timeout

  void flash_all_tiles(){
    for ( int i = 0; ( i < Constants.NUMBER_TILES); i++){
      setState(() {
        appState.flash_tile = i;
      });
      start_flash_timeout(Constants.TILE_FLASH_DURATION);
    }
  }

} // class CirclesAppState

应用状态.dart:

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

class AppState {
  int flash_tile;

  AppState({
    this.flash_tile = -1,
  });

  void set_flash_tile ( int flash_tile) {
    this.flash_tile = flash_tile;
  } // set_flash_tile

  @override
  String toString() {
    return ( 'AppState{flash_tile: $flash_tile}');
  } // toString()

} // class AppState

circles.dart:

// 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 'appstate.dart';
import 'constants.dart';
import 'circle_colors.dart';

class Circles extends StatefulWidget {
  final AppState appState;

  Circles({
    @required this.appState,
    Key key,
  }) : super(key: key);

  @override
  State<StatefulWidget> createState() {
    return Circles_State();
  }
} // class Circles

class Circles_State extends State<Circles> {
  List<GridTile>  grid_tiles = <GridTile>[];

  Circles_State();

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

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

    for (int i = 0; (i < Constants.NUMBER_TILES); i++) {
      Color tile_color = ( widget.appState.flash_tile == i) ?
          Circle_Colors.bright_colors[i] :
          Circle_Colors.normal_colors[i];

      grid_tiles.add(new_circle_tile(tile_color, i));
    }
    return (grid_tiles);
  } // create_circle_tiles

  @override // Circles_State
  Widget build(BuildContext context) {
    return GridView.count(
      shrinkWrap: true,
      crossAxisCount: Constants.CROSS_AXIS_COUNT,
      childAspectRatio: 1.0,
      padding: const EdgeInsets.all(4.0),
      mainAxisSpacing: Constants.MAIN_AXIS_SPACING,
      crossAxisSpacing: Constants.CROSS_AXIS_SPACING,
      children: create_circle_tiles(),
    );
  }
} // class Circles_State

感谢您提供的任何帮助。

最佳答案

您的方法的问题在于您的 flash_all_tiles() 方法。 setState() 为每个循环值调用,但最终结果是,当构建新框架时,它保存的值是最后一次迭代的值,因此您看不到动画。

这用动画更容易实现。对 CirclesAppState 使用以下代码,您将看到它是动画的。

class CirclesAppState extends State<CirclesApp> with SingleTickerProviderStateMixin {
  AnimationController controller;
  Animation animation;

  AppState appState = AppState(flash_tile: -1);

  @override
  void initState() {
    super.initState();

    controller = AnimationController(duration: Duration(seconds: 2), vsync: this);
    animation = IntTween(begin: -1, end: Constants.NUMBER_TILES).animate(controller)
    ..addListener(() {
      setState(() {
        appState = AppState(flash_tile: animation.value);
      });
    })
    ..addStatusListener((status) {
      if (status == AnimationStatus.completed) {
        controller.reverse();
      }
    });

  } // initState()

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: "Title",
      home: Scaffold(
        appBar: AppBar(
            title: Text("Title"),
            actions: <Widget>[
              IconButton(
                icon: Icon(Icons.replay),
                onPressed: () => flash_all_tiles(),
              )
            ]
        ),
        body: Column(
          children: [
            Circles (
              appState: appState,
            ),
          ],
        ),
      ),
    );
  }

  void flash_all_tiles(){
    controller.forward();
  }
} 

关于dart - 在点击图标时呈现屏幕,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52523548/

相关文章:

Flutter - Flutter 版本管理 (fvm) 包在 Windows 中不起作用

dart - 类型 '_InternalLinkedHashMap<String, dynamic>' 不是类型 'List<Map<String, dynamic>>' 的子类型

dart - 打包:flutter/src/widgets/overlay. dart':失败的断言:第133行pos 12: '_overlay != null':

dart - Flutter - 创建不同类型的列表 - 示例 (i) => i % 6 == 0 ?

json - 如何将具有日期属性的json数据转换为dart

Flutter:禁用带有资源作为图标的 IconButton

ios - Flutter - 不允许操作(在项目 'url_launcher' 的目标 'Pods' 中)

dart - Flutter 中的卡片按钮如何像 Reddit App 一样合在一起?

Dart int 和 double 被拘留?被相同()特殊对待?

forms - 如何从另一个 dart 文件中调用有状态小部件(有表单)方法?- Flutter