Flutter 空值转盘颤振上使用的空检查运算符

Flutter 空值转盘颤振上使用的空检查运算符,flutter,carousel,Flutter,Carousel,早上好, 我试图在主页上放置一个转盘,查找Firebase数据,但由于某些原因,在我第一次加载应用程序时,它会显示以下消息: ════════ Exception caught by widgets library ═════════════════════════════════════ ══════════════════ The following _CastError was thrown building DotsIndicator (animation: PageController

早上好, 我试图在主页上放置一个转盘,查找Firebase数据,但由于某些原因,在我第一次加载应用程序时,它会显示以下消息:

════════ Exception caught by widgets library ═════════════════════════════════════ ══════════════════
The following _CastError was thrown building DotsIndicator (animation: PageController # 734f9 (one client, offset 0.0), dirty, state: _AnimatedState # 636ca):
Null check operator used on a null value
屏幕如下所示:

在进行热重新加载后,错误继续出现,但图像已成功加载,有什么提示吗

家庭经理:

import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:provantagens_app/models/section.dart';

class HomeManager extends ChangeNotifier{
  HomeManager({this.images}){
    _loadSections();
    images = images ?? [];
  }


  void addSection(Section section){
    _editingSections.add(section);
    notifyListeners();
  }



  final List<dynamic> _sections = [];
  List<String> images;
  List<dynamic> newImages;
  List<dynamic> _editingSections = [];

  bool editing = false;
  bool loading = false;
  int index, totalItems;




  final Firestore firestore = Firestore.instance;


  Future<void> _loadSections() async{
    loading = true;
    firestore.collection('home').snapshots().listen((snapshot){
      _sections.clear();
      for(final DocumentSnapshot document in snapshot.documents){
        _sections.add( Section.fromDocument(document));
       images = List<String>.from(document.data['images'] as List<dynamic>);
      }
    });
    loading = false;
    notifyListeners();

  }

  List<dynamic>  get sections {
    if(editing)
      return _editingSections;
    else
      return _sections;
  }

  void enterEditing({Section section}){
    editing = true;

    _editingSections = _sections.map((s) => s.clone()).toList();

    defineIndex(section: section);

    notifyListeners();
  }


  void saveEditing() async{
    bool valid = true;
    for(final section in _editingSections){
      if(!section.valid()) valid = false;
    }
    if(!valid) return;
    loading = true;
    notifyListeners();


    for(final section in _editingSections){
      await section.save();
    }

    for(final section in List.from(_sections)){
      if(!_editingSections.any((s) => s.id == section.id)){
        await section.delete();
      }
    }

    loading = false;
    editing = false;
    notifyListeners();
  }

  void discardEditing(){
    editing = false;
    notifyListeners();
  }

  void removeSection(Section section){
    _editingSections.remove(section);
    notifyListeners();
  }

  void onMoveUp(Section section){
    int index = _editingSections.indexOf(section);

    if(index != 0) {
      _editingSections.remove(section);
      _editingSections.insert(index - 1, section);
      index = _editingSections.indexOf(section);
    }
    notifyListeners();
  }

  HomeManager clone(){
    return HomeManager(
      images: List.from(images),

    );
  }



  void onMoveDown(Section section){

    index = _editingSections.indexOf(section);
    totalItems = _editingSections.length;
    if(index < totalItems - 1){
      _editingSections.remove(section);
      _editingSections.insert(index + 1, section);
      index = _editingSections.indexOf(section);
    }else{
    }
    notifyListeners();
  }

  void defineIndex({Section section}){
    index = _editingSections.indexOf(section);
    totalItems = _editingSections.length;
    notifyListeners();
  }
}
import'包:cloud_firestore/cloud_firestore.dart';
进口“包装:颤振/cupertino.dart”;
进口“包装:颤振/材料.省道”;
导入“package:provantagens_app/models/section.dart”;
类HomeManager扩展了ChangeNotifier{
家庭管理器({this.images}){
_加载段();
图像=图像???[];
}
无效添加节(节){
_编辑节。添加(节);
notifyListeners();
}
最终清单_部分=[];
列出图像;
列出新图像;
列表_editingSections=[];
布尔编辑=假;
布尔加载=假;
整数索引,总计项;
最终Firestore Firestore=Firestore.instance;
Future\u loadSections()异步{
加载=真;
firestore.collection('home').snapshots().listen((快照){
_节。清除();
用于(最终文档snapshot.documents中的snapshot文档){
_节.添加(节.来自文件(文件));
images=List.from(document.data['images']作为列表);
}
});
加载=假;
notifyListeners();
}
列出获取部分{
如果(编辑)
返回编辑部分;
其他的
返回部分;
}
无效输入编辑({Section}){
编辑=真;
_editingSections=_sections.map((s)=>s.clone()).toList();
定义索引(章节:章节);
notifyListeners();
}
void saveEditing()异步{
bool valid=true;
用于(编辑部分中的最后一部分){
如果(!section.valid())valid=false;
}
如果(!有效)返回;
加载=真;
notifyListeners();
用于(编辑部分中的最后一部分){
等待节。保存();
}
用于(列表中的最后一节。从(_节)){
如果(!\u编辑节.any((s)=>s.id==section.id)){
等待节。删除();
}
}
加载=假;
编辑=假;
notifyListeners();
}
无效编辑(){
编辑=假;
notifyListeners();
}
无效清除(截面){
_编辑节。删除(节);
notifyListeners();
}
移动时无效(部分){
int index=_editingSections.indexOf(section);
如果(索引!=0){
_编辑节。删除(节);
_编辑章节。插入(索引-1,章节);
索引=_editingSections.indexOf(section);
}
notifyListeners();
}
HomeManager克隆(){
返回家庭管理器(
图像:列表。从(图像),
);
}
移动时无效(截面){
索引=_editingSections.indexOf(section);
totalItems=_editingSections.length;
如果(索引
主屏幕:

import 'package:carousel_pro/carousel_pro.dart';
import 'package:flutter/material.dart';
import 'package:provantagens_app/commom/custom_drawer.dart';
import 'package:provantagens_app/commom/custom_icons_icons.dart';
import 'package:provantagens_app/models/home_manager.dart';
import 'package:provantagens_app/models/section.dart';
import 'package:provantagens_app/screens/home/components/home_carousel.dart';
import 'package:provantagens_app/screens/home/components/menu_icon_tile.dart';
import 'package:provider/provider.dart';
import 'package:url_launcher/url_launcher.dart';


// ignore: must_be_immutable
class HomeScreen extends StatelessWidget {

  HomeManager homeManager;
  Section section;
  List<Widget> get children => null;
  String videoUrl = 'https://www.youtube.com/watch?v=VFnDo3JUzjs';
  int index;
  var _tapPosition;


  @override
  Widget build(BuildContext context) {
    return Container(
      decoration: BoxDecoration(
          gradient: LinearGradient(colors: const [
            Colors.white,
            Colors.white,
          ], begin: Alignment.topCenter, end: Alignment.bottomCenter)),
      child: Scaffold(
          backgroundColor: Colors.transparent,
          drawer: CustomDrawer(),
          appBar: AppBar(
            backgroundColor: Colors.transparent,
            iconTheme: IconThemeData(color: Colors.black),
            title: Text('Página inicial', style: TextStyle(color: Color.fromARGB(255, 30, 158, 8))),
            centerTitle: true,
            actions: <Widget>[
              Divider(),
            ],
          ),
          body: Consumer<HomeManager>(
            builder: (_, homeManager, __){
              return ListView(children: <Widget>[
                AspectRatio(
                  aspectRatio: 1,
                  child:HomeCarousel(homeManager),
                ),
                Column(
                  children: <Widget>[
                    Container(
                      height: 50,
                    ),
                    Divider(
                      color: Colors.black,
                    ),
                    Row(
                      mainAxisAlignment: MainAxisAlignment.spaceAround,
                      children: [
                        Padding(
                          padding: const EdgeInsets.only(left:12.0),
                          child: MenuIconTile(title: 'Parceiros', iconData: Icons.apartment, page: 1,),
                        ),
                        Padding(
                          padding: const EdgeInsets.only(left:7.0),
                          child: MenuIconTile(title: 'Beneficios', iconData: Icons.card_giftcard, page: 2,),
                        ),
                        Padding(
                          padding: const EdgeInsets.only(right:3.0),
                          child: MenuIconTile(title: 'Suporte', iconData: Icons.help_outline, page: 6,),
                        ),
                      ],
                    ),
                    Row(
                      mainAxisAlignment: MainAxisAlignment.spaceAround,
                      children: [
                        MenuIconTile(iconData: Icons.assignment,
                            title: 'Dados pessoais',
                            page: 3)
                        ,
                        MenuIconTile(iconData: Icons.credit_card_outlined,
                            title: 'Meu cartão',
                            page: 4)
                        ,
                        MenuIconTile(iconData: Icons.account_balance_wallet_outlined,
                          title: 'Pagamento',
                          page: 5,)
                        ,
                      ],
                    ),
                    Divider(
                      color: Colors.black,
                    ),
                    Container(
                      height: 50,
                    ),
                    Consumer<HomeManager>(
                      builder: (_, sec, __){
                        return RaisedButton(
                          child: Text('Teste'),
                          onPressed: (){
                            Navigator.of(context)
                                .pushReplacementNamed('/teste',
                                arguments: sec);
                          },
                        );
                      },
                    ),
                    Text('Saiba onde usar o seu', style: TextStyle(color: Colors.black, fontSize: 20),),
                    Text('Cartão Pró Vantagens', style: TextStyle(color: Color.fromARGB(255, 30, 158, 8), fontSize: 30),),
                    AspectRatio(
                      aspectRatio: 1,
                      child: Image.network(
                        'https://static.wixstatic.com/media/d170e1_80b5f6510f5841c19046f1ed5bca71e4~mv2.png/v1/fill/w_745,h_595,al_c,q_90,usm_0.66_1.00_0.01/Arte_Cart%C3%83%C2%B5es.webp',
                        fit: BoxFit.fill,
                      ),
                    ),
                    Divider(),
                    Container(
                      height: 150,
                      child: Row(
                        children: [
                          AspectRatio(
                            aspectRatio: 1,
                            child: Image.network(
                              'https://static.wixstatic.com/media/d170e1_486dd638987b4ef48d12a4bafee20e80~mv2.png/v1/fill/w_684,h_547,al_c,q_90,usm_0.66_1.00_0.01/Arte_Cart%C3%83%C2%B5es_2.webp',
                              fit: BoxFit.fill,
                            ),
                          ),
                          Padding(
                            padding: const EdgeInsets.only(left:20.0),
                            child: RichText(
                              text: TextSpan(children: <TextSpan>[
                                TextSpan(
                                  text: 'Adquira já o seu',
                                  style: TextStyle(
                                    fontSize: 20.0,
                                    fontWeight: FontWeight.bold,
                                    color: Colors.black,
                                  ),
                                ),
                                TextSpan(
                                  text: '\n\CARTÃO PRÓ VANTAGENS',
                                  style: TextStyle(
                                      fontSize: 15.0,
                                      fontWeight: FontWeight.bold,
                                      color: Color.fromARGB(255, 30, 158, 8)),
                                ),
                              ]),
                            ),
                          ),
                        ],
                      ),
                    ),
                    Divider(),
                    tableBeneficios(),
                    Divider(),
                    Padding(
                      padding: const EdgeInsets.all(16.0),
                      child: Column(
                        children: [
                          Text(
                              'O cartão Pró-Vantagens é sediado na cidade de Hortolândia/SP e já está no mercado há mais de 3 anos. Somos um time de profissionais apaixonados por gestão de benefícios e empenhados em gerar o máximo de valor para os conveniados.'),
                          FlatButton(
                              onPressed: () {
                                launch(
                                    'https://www.youtube.com/watch?v=VFnDo3JUzjs');
                              },
                              child: Text('SAIBA MAIS')),
                        ],
                      ),
                    ),
                    Container(
                      color: Color.fromARGB(255, 105, 190, 90),
                      child: Column(
                        children: <Widget>[
                          Row(
                            children: [
                              Padding(
                                padding: const EdgeInsets.all(16),
                                child: Text(
                                  '©  2020 todos os direitos reservados a Cartão Pró Vantagens.',
                                  style: TextStyle(fontSize: 10),
                                ),
                              )
                            ],
                          ),
                          Divider(),
                          Row(
                            children: [
                              Padding(
                                padding: const EdgeInsets.all(16),
                                child: Text(
                                  'Rua Luís Camilo de Camargo, 175 -\n\Centro, Hortolândia (piso superior)',
                                  style: TextStyle(fontSize: 10),
                                ),
                              ),
                              Padding(
                                padding: const EdgeInsets.only(left: 16),
                                child: IconButton(
                                  icon: Icon(CustomIcons.facebook),
                                  color: Colors.black,
                                  onPressed: () {
                                    launch(
                                        'https://www.facebook.com/provantagens/');
                                  },
                                ),
                              ),
                              Padding(
                                padding: const EdgeInsets.only(left: 16),
                                child: IconButton(
                                  icon: Icon(CustomIcons.instagram),
                                  color: Colors.black,
                                  onPressed: () {
                                    launch(
                                        'https://www.instagram.com/cartaoprovantagens/');
                                  },
                                ),
                              ),
                            ],
                          ),
                        ],
                      ),
                    )
                  ],
                ),
              ]);
            },
          )
          ),

    );
  }

  tableBeneficios() {
    return Table(
      defaultColumnWidth: FlexColumnWidth(120.0),
      border: TableBorder(
        horizontalInside: BorderSide(
          color: Colors.black,
          style: BorderStyle.solid,
          width: 1.0,
        ),
        verticalInside: BorderSide(
          color: Colors.black,
          style: BorderStyle.solid,
          width: 1.0,
        ),
      ),
      children: [
        _criarTituloTable(",Plus, Premium"),
        _criarLinhaTable("Seguro de vida\n\(Morte Acidental),X,X"),
        _criarLinhaTable("Seguro de Vida\n\(Qualquer natureza),,X"),
        _criarLinhaTable("Invalidez Total e Parcial,X,X"),
        _criarLinhaTable("Assistência Residencial,X,X"),
        _criarLinhaTable("Assistência Funeral,X,X"),
        _criarLinhaTable("Assistência Pet,X,X"),
        _criarLinhaTable("Assistência Natalidade,X,X"),
        _criarLinhaTable("Assistência Eletroassist,X,X"),
        _criarLinhaTable("Assistência Alimentação,X,X"),
        _criarLinhaTable("Descontos em Parceiros,X,X"),
      ],
    );
  }

  _criarLinhaTable(String listaNomes) {
    return TableRow(
      children: listaNomes.split(',').map((name) {
        return Container(
          alignment: Alignment.center,
          child: RichText(
            text: TextSpan(children: <TextSpan>[
              TextSpan(
                text: name != "X" ? '' : 'X',
                style: TextStyle(
                  fontSize: 20.0,
                  fontWeight: FontWeight.bold,
                  color: Colors.black,
                ),
              ),
              TextSpan(
                text: name != 'X' ? name : '',
                style: TextStyle(
                    fontSize: 10.0,
                    fontWeight: FontWeight.bold,
                    color: Color.fromARGB(255, 30, 158, 8)),
              ),
            ]),
          ),
          padding: EdgeInsets.all(8.0),
        );
      }).toList(),
    );
  }

  _criarTituloTable(String listaNomes) {
    return TableRow(
      children: listaNomes.split(',').map((name) {
        return Container(
          alignment: Alignment.center,
          child: RichText(
            text: TextSpan(children: <TextSpan>[
              TextSpan(
                text: name == "" ? '' : 'Plano ',
                style: TextStyle(
                  fontSize: 15.0,
                  fontWeight: FontWeight.bold,
                  color: Colors.black,
                ),
              ),
              TextSpan(
                text: name,
                style: TextStyle(
                    fontSize: 15.0,
                    fontWeight: FontWeight.bold,
                    color: Color.fromARGB(255, 30, 158, 8)),
              ),
            ]),
          ),
          padding: EdgeInsets.all(8.0),
        );
      }).toList(),
    );
  }
  void _storePosition(TapDownDetails details) {
    _tapPosition = details.globalPosition;
  }
}
import'包:carousel_pro/carousel_pro.dart';
进口“包装:颤振/材料.省道”;
导入“package:provantagens_app/commom/custom_drawer.dart”;
导入“package:provantagens_app/commom/custom_icons_icons.dart”;
导入“package:provantagens_app/models/home_manager.dart”;
导入“package:provantagens_app/models/section.dart”;
导入“包:provantagens_应用程序/屏幕/主页/组件/主页旋转木马.dart”;
导入“包:provantagens_应用程序/屏幕/主页/组件/菜单图标_tile.dart”;
导入“包:provider/provider.dart”;
导入“package:url_launcher/url_launcher.dart”;
//忽略:必须是不可变的
类主屏幕扩展无状态小部件{
家庭经理家庭经理;
部分;
List get children=>null;
字符串videoUrl=https://www.youtube.com/watch?v=VFnDo3JUzjs';
整数指数;
变量位置;
@凌驾
小部件构建(构建上下文){
返回容器(
装饰:盒子装饰(
渐变:线性渐变(颜色:常量)[
颜色,白色,
颜色,白色,
],开始:Alignment.topCenter,结束:Alignment.bottomCenter),
孩子:脚手架(
背景颜色:颜色。透明,
抽屉:CustomDrawer(),
appBar:appBar(
背景颜色:颜色。透明,
iconTheme:IconThemeData(颜色:Colors.black),
标题:文本('Página inicial',样式:TextStyle(颜色:color.fromARGB(255,30,158,8)),
标题:对,
行动:[
分隔符(),
],
),
主体:消费者(
建筑商:(uu,房屋经理,uuu){
返回列表视图(子项:[
AspectRatio(
方面:1,
子女:家庭旋转木马(家庭经理),
),
纵队(
儿童:[
容器(
身高:50,
),
分隔器(
颜色:颜色,黑色,
),
划船(
mainAxisAlignment:mainAxisAlignment.spaceAround,
儿童:[
填充物(
填充:仅限常量边集(左:12.0),
子项:MenuIconTile(标题:“Parceiros”,iconda:Icons.plant,第1页,),
),
填充物(
填充:仅限常量边集(左:7.0),
子项:MenuIconTile(标题:“受益人”,iconda:Icons.card_giftcard,第2页,),
),
if(carouselState.pageController.position.minScrollExtent == null ||
carouselState.pageController.position.maxScrollExtent == null){ ... }
if(!carouselState.pageController.position.hasContentDimensions){ ... }
child: !loading ? HomeCarousel(homeManager) : Center(child:ProgressIndicator()), 
child: isLoading ? HomeCarousel(homeManager) : SplashScreen(), 
class SplashScreen extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Center(
        child: Text('Loading...')
      ),
  


    );
  }
}
@override    
//double get minScrollExtent => _minScrollExtent!;    
// double? _minScrollExtent;    
double get minScrollExtent {    
if (_minScrollExtent == null) {    
    _minScrollExtent = 0.0;    
    }    
return double.parse(_minScrollExtent.toString());    
}    
double? _minScrollExtent;    
@override    
// double get maxScrollExtent => _maxScrollExtent!;    
// double? _maxScrollExtent;    
double get maxScrollExtent {    
if (_maxScrollExtent == null) {    
     _maxScrollExtent = 0.0;    
    }    
return double.parse(_maxScrollExtent.toString());    
}    
double? _maxScrollExtent;