Flutter 测试颤振应用程序时,黑色背景前出现奇怪的蓝色加载圈
我目前正在通过Udacity教程学习颤振开发。在向我的应用程序添加新资产后进行测试时,出现了一个奇怪的黑色屏幕,屏幕上有一个永不结束的蓝色加载圈 这里是一个截图: 这个屏幕什么时候出现?或者为什么?有没有办法让这一切消失 我已尝试重置android emulator并删除对代码的更新 我在GitHub上有代码: 谢谢你的帮助 更新: 我能够解决这个问题,但我不知道为什么会出现这个问题 这是导致问题的文件:Flutter 测试颤振应用程序时,黑色背景前出现奇怪的蓝色加载圈,flutter,dart,Flutter,Dart,我目前正在通过Udacity教程学习颤振开发。在向我的应用程序添加新资产后进行测试时,出现了一个奇怪的黑色屏幕,屏幕上有一个永不结束的蓝色加载圈 这里是一个截图: 这个屏幕什么时候出现?或者为什么?有没有办法让这一切消失 我已尝试重置android emulator并删除对代码的更新 我在GitHub上有代码: 谢谢你的帮助 更新: 我能够解决这个问题,但我不知道为什么会出现这个问题 这是导致问题的文件: // Copyright 2018 The Chromium Authors.
// Copyright 2018 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import 'dart:async';
import 'dart:convert';
import 'package:flutter/material.dart';
import 'backdrop.dart';
import 'category.dart';
import 'category_tile.dart';
import 'unit.dart';
import 'unit_converter.dart';
/// Loads in unit conversion data, and displays the data.
///
/// This is the main screen to our app. It retrieves conversion data from a
/// JSON asset and from an API. It displays the [Categories] in the back panel
/// of a [Backdrop] widget and shows the [UnitConverter] in the front panel.
///
/// While it is named CategoryRoute, a more apt name would be CategoryScreen,
/// because it is responsible for the UI at the route's destination.
class CategoryRoute extends StatefulWidget {
const CategoryRoute();
@override
_CategoryRouteState createState() => _CategoryRouteState();
}
class _CategoryRouteState extends State<CategoryRoute> {
Category _defaultCategory;
Category _currentCategory;
// Widgets are supposed to be deeply immutable objects. We can update and edit
// _categories as we build our app, and when we pass it into a widget's
// `children` property, we call .toList() on it.
// For more details, see https://github.com/dart-lang/sdk/issues/27755
final _categories = <Category>[];
// TODO: Remove _categoryNames as they will be retrieved from the JSON asset
static const _categoryNames = <String>[
'Length',
'Area',
'Volume',
'Mass',
'Time',
'Digital Storage',
'Energy',
'Currency',
];
static const _baseColors = <ColorSwatch>[
ColorSwatch(0xFF6AB7A8, {
'highlight': Color(0xFF6AB7A8),
'splash': Color(0xFF0ABC9B),
}),
ColorSwatch(0xFFFFD28E, {
'highlight': Color(0xFFFFD28E),
'splash': Color(0xFFFFA41C),
}),
ColorSwatch(0xFFFFB7DE, {
'highlight': Color(0xFFFFB7DE),
'splash': Color(0xFFF94CBF),
}),
ColorSwatch(0xFF8899A8, {
'highlight': Color(0xFF8899A8),
'splash': Color(0xFFA9CAE8),
}),
ColorSwatch(0xFFEAD37E, {
'highlight': Color(0xFFEAD37E),
'splash': Color(0xFFFFE070),
}),
ColorSwatch(0xFF81A56F, {
'highlight': Color(0xFF81A56F),
'splash': Color(0xFF7CC159),
}),
ColorSwatch(0xFFD7C0E2, {
'highlight': Color(0xFFD7C0E2),
'splash': Color(0xFFCA90E5),
}),
ColorSwatch(0xFFCE9A9A, {
'highlight': Color(0xFFCE9A9A),
'splash': Color(0xFFF94D56),
'error': Color(0xFF912D2D),
}),
];
// Remove the overriding of initState(). Instead, we use
// didChangeDependencies()
// @override
// void initState() {
// super.initState();
// for (var i = 0; i < _categoryNames.length; i++) {
// var category = Category(
// name: _categoryNames[i],
// color: _baseColors[i],
// iconLocation: Icons.cake,
// units: _retrieveUnitList(_categoryNames[i]),
// );
// if (i == 0) {
// _defaultCategory = category;
// }
// _categories.add(category);
// }
// }
// Uncomment this out. We use didChangeDependencies() so that we can
// wait for our JSON asset to be loaded in (async).
@override
Future<void> didChangeDependencies() async {
super.didChangeDependencies();
// We have static unit conversions located in our
// assets/data/regular_units.json
if (_categories.isEmpty) {
await _retrieveLocalCategories();
}
}
/// Retrieves a list of [Categories] and their [Unit]s
Future<void> _retrieveLocalCategories() async {
// Consider omitting the types for local variables. For more details on Effective
// Dart Usage, see https://www.dartlang.org/guides/language/effective-dart/usage
final json = DefaultAssetBundle
.of(context)
.loadString('assets/data/regular_units.json');
final data = JsonDecoder().convert(await json);
if (data is! Map) {
throw ('Data retrieved from API is not a Map');
}
// TODO: Create Categories and their list of Units, from the JSON asset
}
/// Function to call when a [Category] is tapped.
void _onCategoryTap(Category category) {
setState(() {
_currentCategory = category;
});
}
/// Makes the correct number of rows for the list view, based on whether the
/// device is portrait or landscape.
///
/// For portrait, we use a [ListView]. For landscape, we use a [GridView].
Widget _buildCategoryWidgets(Orientation deviceOrientation) {
if (deviceOrientation == Orientation.portrait) {
return ListView.builder(
itemBuilder: (BuildContext context, int index) {
return CategoryTile(
category: _categories[index],
onTap: _onCategoryTap,
);
},
itemCount: _categories.length,
);
} else {
return GridView.count(
crossAxisCount: 2,
childAspectRatio: 3.0,
children: _categories.map((Category c) {
return CategoryTile(
category: c,
onTap: _onCategoryTap,
);
}).toList(),
);
}
}
// TODO: Delete this function; instead, read in the units from the JSON asset
// inside _retrieveLocalCategories()
/// Returns a list of mock [Unit]s.
List<Unit> _retrieveUnitList(String categoryName) {
// when the app first starts up
return List.generate(10, (int i) {
i += 1;
return Unit(
name: '$categoryName Unit $i',
conversion: i.toDouble(),
);
});
}
@override
Widget build(BuildContext context) {
if (_categories.isEmpty) {
return Center(
child: Container(
height: 180.0,
width: 180.0,
child: CircularProgressIndicator(),
),
);
}
// Based on the device size, figure out how to best lay out the list
// You can also use MediaQuery.of(context).size to calculate the orientation
assert(debugCheckHasMediaQuery(context));
final listView = Padding(
padding: EdgeInsets.only(
left: 8.0,
right: 8.0,
bottom: 48.0,
),
child: _buildCategoryWidgets(MediaQuery.of(context).orientation),
);
return Backdrop(
currentCategory:
_currentCategory == null ? _defaultCategory : _currentCategory,
frontPanel: _currentCategory == null
? UnitConverter(category: _defaultCategory)
: UnitConverter(category: _currentCategory),
backPanel: listView,
frontTitle: Text('Unit Converter'),
backTitle: Text('Select a Category'),
);
}
}
// Copyright 2018 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import 'dart:async';
import 'dart:convert';
import 'package:flutter/material.dart';
import 'backdrop.dart';
import 'category.dart';
import 'category_tile.dart';
import 'unit.dart';
import 'unit_converter.dart';
/// Loads in unit conversion data, and displays the data.
///
/// This is the main screen to our app. It retrieves conversion data from a
/// JSON asset and from an API. It displays the [Categories] in the back panel
/// of a [Backdrop] widget and shows the [UnitConverter] in the front panel.
///
/// While it is named CategoryRoute, a more apt name would be CategoryScreen,
/// because it is responsible for the UI at the route's destination.
class CategoryRoute extends StatefulWidget {
const CategoryRoute();
@override
_CategoryRouteState createState() => _CategoryRouteState();
}
class _CategoryRouteState extends State<CategoryRoute> {
Category _defaultCategory;
Category _currentCategory;
// Widgets are supposed to be deeply immutable objects. We can update and edit
// _categories as we build our app, and when we pass it into a widget's
// `children` property, we call .toList() on it.
// For more details, see https://github.com/dart-lang/sdk/issues/27755
final _categories = <Category>[];
// TODO: Remove _categoryNames as they will be retrieved from the JSON asset
static const _categoryNames = <String>[
'Length',
'Area',
'Volume',
'Mass',
'Time',
'Digital Storage',
'Energy',
'Currency',
];
static const _baseColors = <ColorSwatch>[
ColorSwatch(0xFF6AB7A8, {
'highlight': Color(0xFF6AB7A8),
'splash': Color(0xFF0ABC9B),
}),
ColorSwatch(0xFFFFD28E, {
'highlight': Color(0xFFFFD28E),
'splash': Color(0xFFFFA41C),
}),
ColorSwatch(0xFFFFB7DE, {
'highlight': Color(0xFFFFB7DE),
'splash': Color(0xFFF94CBF),
}),
ColorSwatch(0xFF8899A8, {
'highlight': Color(0xFF8899A8),
'splash': Color(0xFFA9CAE8),
}),
ColorSwatch(0xFFEAD37E, {
'highlight': Color(0xFFEAD37E),
'splash': Color(0xFFFFE070),
}),
ColorSwatch(0xFF81A56F, {
'highlight': Color(0xFF81A56F),
'splash': Color(0xFF7CC159),
}),
ColorSwatch(0xFFD7C0E2, {
'highlight': Color(0xFFD7C0E2),
'splash': Color(0xFFCA90E5),
}),
ColorSwatch(0xFFCE9A9A, {
'highlight': Color(0xFFCE9A9A),
'splash': Color(0xFFF94D56),
'error': Color(0xFF912D2D),
}),
];
// Remove the overriding of initState(). Instead, we use
// didChangeDependencies()
// @override
// void initState() {
// super.initState();
// for (var i = 0; i < _categoryNames.length; i++) {
// var category = Category(
// name: _categoryNames[i],
// color: _baseColors[i],
// iconLocation: Icons.cake,
// units: _retrieveUnitList(_categoryNames[i]),
// );
// if (i == 0) {
// _defaultCategory = category;
// }
// _categories.add(category);
// }
// }
// Uncomment this out. We use didChangeDependencies() so that we can
// wait for our JSON asset to be loaded in (async).
@override
Future<void> didChangeDependencies() async {
super.didChangeDependencies();
// We have static unit conversions located in our
// assets/data/regular_units.json
if (_categories.isEmpty) {
await _retrieveLocalCategories();
}
}
/// Retrieves a list of [Categories] and their [Unit]s
Future<void> _retrieveLocalCategories() async {
// Consider omitting the types for local variables. For more details on Effective
// Dart Usage, see https://www.dartlang.org/guides/language/effective-dart/usage
final json = DefaultAssetBundle
.of(context)
.loadString('assets/data/regular_units.json');
final data = JsonDecoder().convert(await json);
if (data is! Map) {
throw ('Data retrieved from API is not a Map');
}
// TODO: Create Categories and their list of Units, from the JSON asset
}
/// Function to call when a [Category] is tapped.
void _onCategoryTap(Category category) {
setState(() {
_currentCategory = category;
});
}
/// Makes the correct number of rows for the list view, based on whether the
/// device is portrait or landscape.
///
/// For portrait, we use a [ListView]. For landscape, we use a [GridView].
Widget _buildCategoryWidgets(Orientation deviceOrientation) {
if (deviceOrientation == Orientation.portrait) {
return ListView.builder(
itemBuilder: (BuildContext context, int index) {
return CategoryTile(
category: _categories[index],
onTap: _onCategoryTap,
);
},
itemCount: _categories.length,
);
} else {
return GridView.count(
crossAxisCount: 2,
childAspectRatio: 3.0,
children: _categories.map((Category c) {
return CategoryTile(
category: c,
onTap: _onCategoryTap,
);
}).toList(),
);
}
}
// TODO: Delete this function; instead, read in the units from the JSON asset
// inside _retrieveLocalCategories()
/// Returns a list of mock [Unit]s.
List<Unit> _retrieveUnitList(String categoryName) {
// when the app first starts up
return List.generate(10, (int i) {
i += 1;
return Unit(
name: '$categoryName Unit $i',
conversion: i.toDouble(),
);
});
}
@override
Widget build(BuildContext context) {
if (_categories.isEmpty) {
return Center(
child: Container(
height: 180.0,
width: 180.0,
child: CircularProgressIndicator(),
),
);
}
// Based on the device size, figure out how to best lay out the list
// You can also use MediaQuery.of(context).size to calculate the orientation
assert(debugCheckHasMediaQuery(context));
final listView = Padding(
padding: EdgeInsets.only(
left: 8.0,
right: 8.0,
bottom: 48.0,
),
child: _buildCategoryWidgets(MediaQuery.of(context).orientation),
);
return Backdrop(
currentCategory:
_currentCategory == null ? _defaultCategory : _currentCategory,
frontPanel: _currentCategory == null
? UnitConverter(category: _defaultCategory)
: UnitConverter(category: _currentCategory),
backPanel: listView,
frontTitle: Text('Unit Converter'),
backTitle: Text('Select a Category'),
);
}
}
//作者版权所有。版权所有。
//此源代码的使用受BSD样式许可证的约束,该许可证可以
//在许可证文件中找到。
导入“dart:async”;
导入“dart:convert”;
进口“包装:颤振/材料.省道”;
导入“background.dart”;
导入“category.dart”;
导入“类别_tile.dart”;
输入“单位省道”;
输入“单位单位换算器.省道”;
///加载单位转换数据,并显示数据。
///
///这是我们应用程序的主屏幕。它从数据库中检索转换数据
///JSON资产和来自API的数据。它在后面板中显示[类别]
///显示[Background]小部件,并在前面板中显示[UnitConverter]。
///
///虽然它被命名为CategoryRoute,但更合适的名称是CategoryScreen,
///因为它负责路由目的地的UI。
类CategoryRoute扩展StatefulWidget{
常量范畴();
@凌驾
_CategoryRouteState createState()=>U CategoryRouteState();
}
类_categoryroutstate扩展状态{
类别_defaultCategory;
类别_currentCategory;
//小部件应该是高度不可变的对象。我们可以更新和编辑
//_当我们构建应用程序时,以及当我们将其传递到小部件的
//“children”属性,我们称之为.toList()。
//有关详细信息,请参阅https://github.com/dart-lang/sdk/issues/27755
最终_类别=[];
//TODO:删除_categoryNames,因为它们将从JSON资产中检索
静态常数_categoryNames=[
“长度”,
"地区",,
"卷",,
"弥撒",,
“时间”,
“数字存储”,
“能源”,
"货币",,
];
静态常数_基色=[
色样(0xFF6AB7A8{
“高光”:颜色(0xFF6AB7A8),
“飞溅”:颜色(0xFF0ABC9B),
}),
色样(0xFFFFD28E{
“高光”:颜色(0xFFFFD28E),
“飞溅”:颜色(0xFFFF41C),
}),
色样(0xFFFFB7DE{
“高光”:颜色(0xFFFFB7DE),
“飞溅”:颜色(0xFFF94CBF),
}),
色样(0xFF8899A8{
“高光”:颜色(0xFF8899A8),
“飞溅”:颜色(0xFFA9CAE8),
}),
色样(0xFFEAD37E{
“高光”:颜色(0xFFEAD37E),
“飞溅”:颜色(0xFFFF070),
}),
色样(0xFF81A56F{
“高光”:颜色(0xFF81A56F),
“飞溅”:颜色(0xFF7CC159),
}),
色样(0xFFD7C0E2{
“高光”:颜色(0xFFD7C0E2),
“飞溅”:颜色(0xFFCA90E5),
}),
色样(0xFFCE9A9A{
“高光”:颜色(0xFFCE9A9A),
“飞溅”:颜色(0xFFF94D56),
“错误”:颜色(0xFF912D2D),
}),
];
//删除对initState()的重写
//didChangeDependencies()
//@覆盖
//void initState(){
//super.initState();
//对于(变量i=0;i<_categoryNames.length;i++){
//var类别=类别(
//名称:_categoryNames[i],
//颜色:基色[i],
//iconLocation:Icons.cake,
//单位:_retrieveUnitList(_categoryNames[i]),
// );
//如果(i==0){
//_defaultCategory=类别;
// }
//_类别。添加(类别);
// }
// }
//取消对此的注释。我们使用didChangeDependencies()以便
//等待加载JSON资产(异步)。
@凌驾
Future didChangeDependencies()异步{
super.didChangeDependencies();
//我们有静态单位转换位于我们的
//资产/数据/常规单位.json
如果(_categories.isEmpty){
等待检索目录();
}
}
///检索[类别]及其[单位]的列表
未来_retrievelocategories()异步{
/考虑省略局部变量的类型。
//省道使用,请参阅https://www.dartlang.org/guides/language/effective-dart/usage
最终json=DefaultAssetBundle
.of(上下文)
.loadString('assets/data/regular_units.json');
final data=JsonDecoder().convert(等待json);
if(数据为!地图){
throw('从API检索的数据不是映射');
}
//TODO:从JSON资产创建类别及其单位列表
}
///点击[Category]时调用的函数。
void _onCategoryTap(类别){
设置状态(){
_当前类别=类别;
});
}
///根据
///设备为纵向或横向。
///
///对于纵向,我们使用[ListView]。对于横向,我们使用[GridView]。
Widget\u buildCategoryWidgets(定向设备定向){
if(deviceOrientation==方向.纵向){
返回ListView.builder(
itemBuilder:(构建上下文,int索引){
返回分类(
类别:_类别[索引],
onTap:_onCategoryTap,
);
},
itemCount:_categories.length,
);
}否则{
返回GridView.count(
交叉轴计数:2,
childAspectRatio:3.0,
子类:_categories.map((c类){
返回分类(
类别:c,
onTap:_onCategoryTap,
);
}).toList(),
);
}
}
//TODO:删除此函数;而是从JSON资产中读入单位
//内部(检索VelocialCategories)
///返回
if (_categories.isEmpty) {
return Center(
child: Container(
height: 180.0,
width: 180.0,
child: CircularProgressIndicator(),
),
);
}
if (_categories.isEmpty) {
return Center(
child: Container(
),
);
}