在图标水龙头上渲染屏幕 [英] Rendering a screen on icon tap

查看:58
本文介绍了在图标水龙头上渲染屏幕的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我仍然无法通过点击图标来重新绘制应用程序屏幕.我正在使用GitHub上的Vanilla项目作为指南.我显然错过了一些东西!

I am still not able to get an icon tap to cause the redrawing of an app screen. I am using the Vanilla project on GitHub as a guide. I have obviously missed something!

该应用程序在GridView中显示9个圆圈. main.dart包含runApp(CirclesApp());. CirclesApp(在circleapp.dart中)包含通过调用Circles(在circle.dart中)来显示9个圆圈的代码. CirclesApp创建AppState(在appstate.dart中),该状态将传递给Circles. CirclesApp包含AppBar,该AppBar带有图标,在点击该图标时会调用函数flash_all_tiles().该函数迭代9个图块,将flash_tile值设置为当前图块的索引,并延迟500 ms.计时器超时功能将flash_tile值重置为-1.

The app displays 9 circles in a GridView. main.dart contains runApp(CirclesApp());. CirclesApp (in circlesapp.dart) contains code to display the 9 circles by invoking Circles (in circles.dart). CirclesApp creates the AppState (in appstate.dart) that will be passed to Circles. CirclesApp contains the AppBar that has the icon that, when tapped, invokes the function flash_all_tiles(). That function iterates through the 9 tiles, setting the flash_tile value to the index of the current tile and delays for 500 ms. The timer time-out function resets the flash_tile value to -1.

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

What I had hoped to see, upon tapping the AppBar Icons.replay icon, was each circle flash in turn. I do see a change in the Home Bar buttons, but no change to the brightness of each circle. The color of each circle is determined by the create_circle_tiles function (in circles.dart) by comparing the current tile index to widget.appState.flash_tile.

该应用的代码如下.不包括文件circle_colors.dart,constants.dart和strings.dart.

The code for the app follows. The files circle_colors.dart, constants.dart, and strings.dart are not included.

main.dart:

main.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:

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

appstate.dart:

appstate.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:

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

感谢您可以提供的任何帮助.

Thanks for any help you can provide.

推荐答案

您的方法存在的问题属于您的flash_all_tiles()方法.对于每个循环值都调用setState(),但是在构建新帧时,最终结果是它持有的值是最后一次迭代之一,因此您看不到动画.

The problem with your approach is within your flash_all_tiles()method. setState() is called for every loop value, but the end result, when the new frame is built, is that the value it holds is the one of the last iteration, so you are not able to see the animation.

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

This is easier implemented with an animation. Use the following code for the CirclesAppState and you will see it animate.

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();
  }
} 

这篇关于在图标水龙头上渲染屏幕的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆