如何修复 RangeError (index): Invalid value: Only valid value is 0: 1 in Flutter

时间:2021-02-27 20:48:59

标签: flutter dart

我有一个屏幕,它代表一个包含多张照片的相册。用户可以单击任何照片以全屏查看它,然后选择删除它。但是当我从数组中删除最后一个位置的照片时,我收到了下一个错误:

The following RangeError was thrown building PhotoFullscreenPage(dirty, dependencies: [MediaQuery], state: _PhotoFullscreenPageState#4ce05):
RangeError (index): Invalid value: Only valid value is 0: 1

The relevant error-causing widget was: 
  PhotoFullscreenPage file:/.../lib/views/photos/photosAlbumPage.dart:78:33

如果我从数组中删除所有照片,则会收到此错误:

The following RangeError was thrown building PhotoFullscreenPage(dirty, dependencies: [MediaQuery], state: _PhotoFullscreenPageState#48547):
RangeError (index): Invalid value: Valid value range is empty: 0

The relevant error-causing widget was: 
  PhotoFullscreenPage file:/.../lib/views/photos/photosAlbumPage.dart:78:33

这是我的两个类的代码:

PhotosAlbumPage.dart

import 'package:flutter/material.dart';
import 'package:flutter_staggered_grid_view/flutter_staggered_grid_view.dart';

import 'package:my_app/models/photoField.dart';
import 'package:my_app/views/photos/photoFullscreenPage.dart';

class PhotosAlbumPage extends StatefulWidget {
  final PhotoField photoField;

  PhotosAlbumPage({Key key, this.photoField}) : super(key: key);

  @override
  _PhotosAlbumPageState createState() => _PhotosAlbumPageState();
}

class _PhotosAlbumPageState extends State<PhotosAlbumPage> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: _appBar(),
      body: _body(),
    );
  }

  Widget _appBar() {
    return AppBar(
      title: Text('${widget.photoField.titleDescription} - Photos Album'),
      centerTitle: true,
      leading: _backButton(),
    );
  }

  Widget _backButton() {
    return IconButton(
      icon: Icon(Icons.arrow_back, color: Colors.white),
      onPressed: () {
        _sendDataBackToPhotosPage(context);
      },
    );
  }

  Widget _body() {
    return CustomScrollView(slivers: <Widget>[
      SliverStaggeredGrid.countBuilder(
        crossAxisCount: 2,
        mainAxisSpacing: 10,
        crossAxisSpacing: 10,
        staggeredTileBuilder: (int index) => StaggeredTile.fit(1),
        itemCount: widget.photoField.photoAlbum.length,
        itemBuilder: (context, index) {
          return Container(
            margin: EdgeInsets.all(10),
            child: GestureDetector(
              child: ClipRRect(
                borderRadius: BorderRadius.all(Radius.circular(20)),
                child:
                    Image.asset(widget.photoField.photoAlbum[index].photoPath),
              ),
              onTap: () async {
                print('Click on photo: $index');
                _awaitReturnValueFromPhotoFullscreenPage(
                    context: context,
                    photoField: widget.photoField,
                    photoIndex: index);
              },
            ),
          );
        },
      ),
    ]);
  }

  void _awaitReturnValueFromPhotoFullscreenPage(
      {BuildContext context, PhotoField photoField, int photoIndex}) async {
    final result = await Navigator.push(
        context,
        MaterialPageRoute(
          builder: (context) => PhotoFullscreenPage(
              photoField: photoField, photoIndex: photoIndex), // here the error is thrown
        ));

    setState(() {
      widget.photoField.photoAlbum = result;

      if (widget.photoField.photoAlbum.isEmpty) {
        Navigator.of(context).pop();
      }
    });
  }

  void _sendDataBackToPhotosPage(BuildContext context) {
    PhotoField photoField = widget.photoField;
    Navigator.pop(context, photoField);
  }
}

PhotoFullscreenPage.dart

import 'package:flutter/material.dart';
import 'package:my_app/models/photo.dart';
import 'package:my_app/models/photoField.dart';

class PhotoFullscreenPage extends StatefulWidget {
  final PhotoField photoField;
  final int photoIndex;

  const PhotoFullscreenPage({Key key, this.photoField, this.photoIndex})
      : super(key: key);
  @override
  _PhotoFullscreenPageState createState() => _PhotoFullscreenPageState();
}

class _PhotoFullscreenPageState extends State<PhotoFullscreenPage> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: _appBar(),
      body: _body(),
    );
  }

  Widget _appBar() {
    return AppBar(
      title: Text(
          '${widget.photoField.titleDescription} - Photo ${widget.photoIndex}'),
      centerTitle: true,
      leading: _backButton(),
    );
  }

  Widget _backButton() {
    return IconButton(
      icon: Icon(Icons.arrow_back, color: Colors.white),
      onPressed: () {
        _sendDataBackToPhotosAlbumPage(context);
      },
    );
  }

  Widget _body() {
    return Container(
      child: Column(
        crossAxisAlignment: CrossAxisAlignment.center,
        mainAxisAlignment: MainAxisAlignment.center,
        children: <Widget>[
          Image.asset(
              '${widget.photoField.photoAlbum[widget.photoIndex].photoPath}'),
          IconButton(
            icon: Image.asset('assets/images/delete_icon.png'),
            iconSize: 70,
            onPressed: () {
              print("Photo will be deleted...");
              setState(() {
                widget.photoField.photoAlbum.removeAt(widget.photoIndex);
              });

              _sendDataBackToPhotosAlbumPage(context);
            },
          ),
        ],
      ),
      width: MediaQuery.of(context).size.width,
      height: MediaQuery.of(context).size.height,
    );
  }

  void _sendDataBackToPhotosAlbumPage(BuildContext context) {
    List<Photo> photoAlbum = widget.photoField.photoAlbum;
    Navigator.pop(context, photoAlbum);
  }
}

请帮我找出错误。谢谢。

1 个答案:

答案 0 :(得分:2)

您必须在访问之前检查 widget.photoField.photoAlbum 的边界:

return Scaffold(
      appBar: _appBar(),
      body: widget.photoField.photoAlbum.length <= widget.photoIndex ? SizedBox() : _body(),
    );

渲染您的空状态而不是示例 SizedBox()