【问题标题】:Null check operator used on a null value Carousel Flutter用于空值的空值检查运算符 Carousel Flutter
【发布时间】:2021-02-25 13:44:48
【问题描述】:

早上好, 我试图在主页上放置一个轮播以查找 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

屏幕看起来像这样:

进行热重载后错误继续出现,但图像加载成功,有什么提示可以做什么吗?

HomeManager:

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 '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;
  }
}

【问题讨论】:

    标签: flutter carousel


    【解决方案1】:

    我 fork 库为我公司的项目创建了一个自定义轮播,自从我们将 Flutter 更新到 2.x 后,我们遇到了同样的问题。

    要解决这个问题,只需更新布尔表达式,如

    if(carouselState.pageController.position.minScrollExtent == null ||
    carouselState.pageController.position.maxScrollExtent == null){ ... }
    

    if(!carouselState.pageController.position.hasContentDimensions){ ... }
    

    Here is flutter's github reference.

    【讨论】:

      【解决方案2】:

      这对我有用

      所以我编辑了 scrollposition.dart 包

      从第 133 行开始

      @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;
      

      【讨论】:

        【解决方案3】:

        只需升级到^3.0.0 在这里查看https://pub.dev/packages/carousel_slider

        【讨论】:

          【解决方案4】:

          我解决了类似的问题如下。您可以利用布尔变量。希望能帮到你。

          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...')
                ),
            
          
          
              );
            }
          }
          

          【讨论】:

            猜你喜欢
            • 2022-01-18
            • 1970-01-01
            • 2023-01-05
            • 2022-06-15
            • 2022-01-05
            • 2021-08-30
            • 2021-12-03
            • 2021-11-06
            • 2021-06-17
            相关资源
            最近更新 更多