图像自行加载,但不是作为随机列表加载。 - 颤振

Images load by themselves, but not as a randomized list. - Flutter

提前感谢您的帮助。

因此,当我在代码的其他区域的容器中使用图像时,我可以正确加载它们,但我也希望其中一些图像在 AppBar 中随机显示。

鉴于它们确实在代码中的其他位置加载,我不怀疑 Pubyaml 错误。

我对 Flutter 还是比较陌生,一般来说都是列表。因此,如果我弄乱了列表本身或它的调用方式,我不会感到惊讶。

它给我这个错误:

Syncing files to device iPhone...
Reloaded 8 of 502 libraries in 411ms.

════════ Exception caught by image resource service ════════════════════════════════════════════════
The following assertion was thrown resolving an image codec:
Unable to load asset: Image(image: AssetImage(bundle: null, name: "images/Mem2.JPG"), frameBuilder: null, loadingBuilder: null, alignment: center, this.excludeFromSemantics: false, filterQuality: low)

When the exception was thrown, this was the stack: 
#0      PlatformAssetBundle.load (package:flutter/src/services/asset_bundle.dart:221:7)
<asynchronous suspension>
#1      AssetBundleImageProvider._loadAsync (package:flutter/src/painting/image_provider.dart:484:44)
#2      AssetBundleImageProvider.load (package:flutter/src/painting/image_provider.dart:469:14)
#3      ImageProvider.resolve.<anonymous closure>.<anonymous closure>.<anonymous closure> (package:flutter/src/painting/image_provider.dart:327:17)
...
Image provider: AssetImage(bundle: null, name: "Image(image: AssetImage(bundle: null, name: "images/Mem2.JPG"), frameBuilder: null, loadingBuilder: null, alignment: center, this.excludeFromSemantics: false, filterQuality: low)")
Image key: AssetBundleImageKey(bundle: PlatformAssetBundle#c99db(), name: "Image(image: AssetImage(bundle: null, name: "images/Mem2.JPG"), frameBuilder: null, loadingBuilder: null, alignment: center, this.excludeFromSemantics: false, filterQuality: low)", scale: 1.0)
════════════════════════════════════════════════════════════════════════════════════════════════════

代码如下:

class ContactProfilePage extends StatefulWidget {
  @override
  _ContactProfilePageState createState() => _ContactProfilePageState();
}

class _ContactProfilePageState extends State<ContactProfilePage> {
  List<Attr> attr = [
    Attr(name: ''),
  ];

  dynamic randAppBarImg = [
    "images/Mem2.JPG",
    "images/Mem3.JPG",
    "images/Mem4.JPG",
    "images/Mem6.jpg",
    "images/memory - 1.jpeg",
    "images/memory - 2.jpeg",
    "images/memory - 3.jpeg",
    "images/memory - 4.jpeg",
    "images/memory - 5.jpeg",
    "images/memory - 6.jpeg",
  ];

  Random rnd;

  Image img() {
    int min = 0;
    int max = randAppBarImg.length - 1;
    rnd = Random();
    int r = min + rnd.nextInt(max - min);
    String image_name = randAppBarImg[r].toString();
    return Image.asset(image_name);
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      floatingActionButton: FloatingActionButton(
        backgroundColor: Colors.lightBlueAccent,
        child: Icon(Icons.add),
        onPressed: () {
          //Modal sheet brings up the whole bottom pane when the plus button is pressed.
          showModalBottomSheet(
            context: context,
            builder: (context) => AddAttrScreen(
              (newAttrTitle) {
                setState(() {
                  //adds the Attr to the list anytime the user presses "Add"
                  attr.add(Attr(name: newAttrTitle));
                });
                Navigator.pop(context);
                //Hides the floating add Attr screen after pressing "Add"
              },
            ),
          );
          //TODO Change it so the categories don't have to be selected every time. Instead, have the add button WITHIN each category.
          // This floating button should instead create a new category.
        },
      ),
      drawer: DrawerMain(),
      body: NestedScrollView(
        //This allows for the top bar to collapse, while retaining the image.
        headerSliverBuilder: (BuildContext context, bool innerBoxIsScrolled) {
          return <Widget>[
            SliverAppBar(
              expandedHeight: 200.0,
              floating: true,
              snap: true,
              pinned: true,
              flexibleSpace: Stack(
                children: <Widget>[
                  Positioned.fill(
                      child: Image.asset(
                    img().toString(),
                    fit: BoxFit.cover,
                  ))
                ],
              ),
            ),
          ];
        },


        body: SingleChildScrollView(
          child: Column(
            mainAxisAlignment: MainAxisAlignment.spaceEvenly,
            children: <Widget>[
              Row(
                mainAxisSize: MainAxisSize.max,
                children: <Widget>[
                  Padding(
                    padding: const EdgeInsets.all(15.0),
                    child: CircleAvatar(
                        maxRadius: 50.0,
                        backgroundImage: AssetImage("images/fox.jpeg")),
                  ),
                  Container(
                    //TODO ADD ON PRESSED FUNCTION TO SOCIAL ICONS
                    margin: EdgeInsets.all(15.0),
                    child: Icon(
                      FontAwesomeIcons.facebook,
                      size: 40.0,
                      color: Color(0xFF306060),
                    ),
                  ),
                  Container(
                    margin: EdgeInsets.all(15.0),
                    child: Icon(
                      FontAwesomeIcons.instagram,
                      size: 40.0,
                      color: Color(0xFF306060),
                    ),
                  ),
                ],
              ),
              Padding(
                padding: const EdgeInsets.only(left: 15.0),
                child: Row(
                  mainAxisAlignment: MainAxisAlignment.start,
                  children: <Widget>[
                    Text(
                      'Armando Pacheco Ortiz',
                      style: TextStyle(
                          fontSize: 25.0,
                          fontWeight: FontWeight.bold,
                          color: Color(0xFF306060)),
                    ),
                  ],
                ),
              ),
              Padding(
                padding: const EdgeInsets.only(left: 15.0),
                child: Row(
                  mainAxisAlignment: MainAxisAlignment.start,
                  children: <Widget>[
                    Text(
                      'Freelance App Developer from Puerto Rico',
                      style: TextStyle(
                          fontSize: 20.0,
                          fontStyle: FontStyle.italic,
                          color: Color(0xFF306060)),
                    ),
                    SizedBox(
                      child: Divider(),
                    ),
                  ],
                ),
              ),
              Padding(
                padding: const EdgeInsets.all(15.0),
                child: Row(
                  children: <Widget>[
                    Text('Memories',
                        style: TextStyle(
                            fontSize: 20.0,
                            fontStyle: FontStyle.italic,
                            color: Color(0xFF306060),
                            fontWeight: FontWeight.bold))
                  ],
                ),
              ),

              //Horizontal scrolling images.
              //TODO These need to update based on uploads, perhaps use something like google's face detection to auto add?
              Padding(
                padding: const EdgeInsets.all(15.0),
                child: SingleChildScrollView(
                  scrollDirection: Axis.horizontal,
                  child: Row(
                    mainAxisAlignment: MainAxisAlignment.spaceEvenly,
                    children: <Widget>[
                      Container(
                        height: 310,
                        width: 200,
                        child: ClipRRect(
                          borderRadius: BorderRadius.circular(20.0),
                          child: (Image.asset(
                            'images/Mem6.jpg',
                            fit: BoxFit.cover,
                          )),
                        ),
                      ),
                      SizedBox(
                        width: 20,
                      ),
                      Container(
                        height: 310,
                        width: 200,
                        //ClipRRect allows for it to have the border radius. Container is painted behind the image.
                        //For that reason, adding a border radius to the container doesn't work.
                        child: ClipRRect(
                          borderRadius: BorderRadius.circular(20.0),
                          child: (Image.asset(
                            'images/Mem2.JPG',
                            fit: BoxFit.cover,
                          )),
                        ),
                      ),
                      SizedBox(
                        width: 20,
                      ),
                      Container(
                        height: 310,
                        width: 200,
                        child: ClipRRect(
                          borderRadius: BorderRadius.circular(20.0),
                          child: (Image.asset(
                            'images/memory - 4.jpeg',
                            fit: BoxFit.cover,
                          )),
                        ),
                      ),


我将代码粘贴到第一张图片,以展示我如何在其他位置设置它。

我不确定问题是出在 appBar 中的随机图像,还是我遗漏了某些代码。 希望有人能对此有所了解!

非常感谢。

更新:

所以这帮了大忙,而且肯定得到了东西 运行!但我确实注意到两个新问题突然出现。

  1. 我不得不将所有图像从 "memory - 6" 重命名为 "Mem6",这最终让它们得以显示。 否则,有时它会恢复为默认的蓝绿色,并且不显示任何内容,除了无法再次加载资产的错误。我想这只是我在不知不觉中造成的命名错误?

  2. 向下滚动会导致应用栏再次"refresh",并随机滚动最轻微的图片,直到您停止。如果我向上滚动,它会再次执行。它不会产生错误,但我猜它确实会因刷新太多而最终使应用程序崩溃。 我将如何解决这个问题?是否有覆盖,或者我应该简单地用一些决赛或 stateless/stateful 小部件创建小部件?我仍在学习行话之类的,所以我为我的无知道歉。

您可以复制粘贴 运行 下面的完整代码
你的 img() 有错误,你 return 一个 Image.asset 并再次包裹在 Image.asset 中导致重复

Image.asset(
             img().toString(),
             fit: BoxFit.cover,
           ))

代码片段 return image_name 的字符串将起作用
并且不要在图像名称

中包含 space
String img() {
    int min = 0;
    int max = randAppBarImg.length - 1;
    rnd = Random();
    int r = min + rnd.nextInt(max - min);
    String image_name = randAppBarImg[r].toString();
    //return Image.asset(image_name);
    return image_name;
  }

工作演示

完整代码

import 'package:flutter/material.dart';
import 'dart:math';
import 'package:font_awesome_flutter/font_awesome_flutter.dart';

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: ContactProfilePage(),
    );
  }
}

class Attr {
  String name;
  Attr({this.name});
}

class ContactProfilePage extends StatefulWidget {
  @override
  _ContactProfilePageState createState() => _ContactProfilePageState();
}

class _ContactProfilePageState extends State<ContactProfilePage> {
  List<Attr> attr = [
    Attr(name: ''),
  ];

  dynamic randAppBarImg = [
    "images/Mem2.JPG",
    "images/Mem3.JPG",
    /*"images/Mem4.JPG",
    "images/Mem6.jpg",
    "images/memory-1.jpeg",
    "images/memory-2.jpeg",
    "images/memory-3.jpeg",
    "images/memory-4.jpeg",
    "images/memory-5.jpeg",
    "images/memory-6.jpeg",*/
  ];

  Random rnd;

  String img() {
    int min = 0;
    int max = randAppBarImg.length - 1;
    rnd = Random();
    int r = min + rnd.nextInt(max - min);
    String image_name = randAppBarImg[r].toString();
    //return Image.asset(image_name);
    return image_name;
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
        floatingActionButton: FloatingActionButton(
          backgroundColor: Colors.lightBlueAccent,
          child: Icon(Icons.add),
          onPressed: () {
            //Modal sheet brings up the whole bottom pane when the plus button is pressed.
            /*       showModalBottomSheet(
              context: context,
              builder: (context) => AddAttrScreen(
                (newAttrTitle) {
                  setState(() {
                    //adds the Attr to the list anytime the user presses "Add"
                    attr.add(Attr(name: newAttrTitle));
                  });
                  Navigator.pop(context);
                  //Hides the floating add Attr screen after pressing "Add"
                },
              ),
            );*/
            //TODO Change it so the categories don't have to be selected every time. Instead, have the add button WITHIN each category.
            // This floating button should instead create a new category.
          },
        ),
        //drawer: DrawerMain(),
        body: NestedScrollView(
            //This allows for the top bar to collapse, while retaining the image.
            headerSliverBuilder:
                (BuildContext context, bool innerBoxIsScrolled) {
              return <Widget>[
                SliverAppBar(
                  expandedHeight: 200.0,
                  floating: true,
                  snap: true,
                  pinned: true,
                  /*flexibleSpace: FlexibleSpaceBar(
                      centerTitle: true,
                      title: Text("",
                          style: TextStyle(
                            color: Colors.white,
                            fontSize: 16.0,
                          )),
                      background: Image.asset(
                        "images/Mem2.JPG",
                        fit: BoxFit.cover,
                      )),*/
                  flexibleSpace: Stack(
                    children: <Widget>[
                      Positioned.fill(
                          child: Image.asset(
                        img().toString(),
                        fit: BoxFit.cover,
                      ))
                    ],
                  ),
                ),
              ];
            },
            body: SingleChildScrollView(
                child: Column(
                    mainAxisAlignment: MainAxisAlignment.spaceEvenly,
                    children: <Widget>[
                  Row(
                    mainAxisSize: MainAxisSize.max,
                    children: <Widget>[
                      Padding(
                        padding: const EdgeInsets.all(15.0),
                        child: CircleAvatar(
                            maxRadius: 50.0,
                            backgroundImage: AssetImage("images/fox.jpeg")),
                      ),
                      Container(
                        //TODO ADD ON PRESSED FUNCTION TO SOCIAL ICONS
                        margin: EdgeInsets.all(15.0),
                        child: Icon(
                          FontAwesomeIcons.facebook,
                          size: 40.0,
                          color: Color(0xFF306060),
                        ),
                      ),
                      Container(
                        margin: EdgeInsets.all(15.0),
                        child: Icon(
                          FontAwesomeIcons.instagram,
                          size: 40.0,
                          color: Color(0xFF306060),
                        ),
                      ),
                    ],
                  ),
                  Padding(
                    padding: const EdgeInsets.only(left: 15.0),
                    child: Row(
                      mainAxisAlignment: MainAxisAlignment.start,
                      children: <Widget>[
                        Text(
                          'Armando Pacheco Ortiz',
                          style: TextStyle(
                              fontSize: 25.0,
                              fontWeight: FontWeight.bold,
                              color: Color(0xFF306060)),
                        ),
                      ],
                    ),
                  ),
                  Padding(
                    padding: const EdgeInsets.only(left: 15.0),
                    child: Row(
                      mainAxisAlignment: MainAxisAlignment.start,
                      children: <Widget>[
                        Text(
                          'Freelance App Developer from Puerto Rico',
                          style: TextStyle(
                              fontSize: 20.0,
                              fontStyle: FontStyle.italic,
                              color: Color(0xFF306060)),
                        ),
                        SizedBox(
                          child: Divider(),
                        ),
                      ],
                    ),
                  ),
                  Padding(
                    padding: const EdgeInsets.all(15.0),
                    child: Row(
                      children: <Widget>[
                        Text('Memories',
                            style: TextStyle(
                                fontSize: 20.0,
                                fontStyle: FontStyle.italic,
                                color: Color(0xFF306060),
                                fontWeight: FontWeight.bold))
                      ],
                    ),
                  ),

                  //Horizontal scrolling images.
                  //TODO These need to update based on uploads, perhaps use something like google's face detection to auto add?
                  Padding(
                      padding: const EdgeInsets.all(15.0),
                      child: SingleChildScrollView(
                          scrollDirection: Axis.horizontal,
                          child: Row(
                              mainAxisAlignment: MainAxisAlignment.spaceEvenly,
                              children: <Widget>[
                                Container(
                                  height: 310,
                                  width: 200,
                                  child: ClipRRect(
                                    borderRadius: BorderRadius.circular(20.0),
                                    child: (Image.asset(
                                      'images/Mem6.jpg',
                                      fit: BoxFit.cover,
                                    )),
                                  ),
                                ),
                                SizedBox(
                                  width: 20,
                                ),
                                Container(
                                  height: 310,
                                  width: 200,
                                  //ClipRRect allows for it to have the border radius. Container is painted behind the image.
                                  //For that reason, adding a border radius to the container doesn't work.
                                  child: ClipRRect(
                                    borderRadius: BorderRadius.circular(20.0),
                                    child: Image.asset(
                                      'images/Mem2.JPG',
                                      fit: BoxFit.cover,
                                    ),
                                  ),
                                ),
                                SizedBox(
                                  width: 20,
                                ),
                                Container(
                                  height: 310,
                                  width: 200,
                                  child: ClipRRect(
                                    borderRadius: BorderRadius.circular(20.0),
                                    child: (Image.asset(
                                      'images/memory-4.jpeg',
                                      fit: BoxFit.cover,
                                    )),
                                  ),
                                ),
                              ])))
                ]))));
  }
}