1

我是flutter的初学者,不太了解Widget的概念。

想把背景图设置为unsplash的随机图,但是想在点击的时候再添加一个按钮请求随机图,但是对Flutter的很多概念感到困惑,不知道怎么完成这个功能。

下面是我目前的代码,不知道怎么改,请大家帮帮我,非常感谢!

import 'package:flutter/material.dart';
void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    // TODO: implement build
    return MaterialApp(
        title: 'Welcome to Flutter',
        theme: new ThemeData(
          brightness: Brightness.light,
      ),
        home: new Scaffold(
          appBar: new AppBar(
            title: new Text("Welcome to Flutter"),
          ),
          body: BackgroundImgDemo()
        ),
    );
  }
}

class BackgroundImgDemo extends StatelessWidget {
  final String imgUrl="https://unsplash.it/1440/3040?random";
  const BackgroundImgDemo({Key key}) : super(key: key);
  @override
  Widget build(BuildContext context) {
    return Container(
      decoration: BoxDecoration(
        image: new DecorationImage(
          fit: BoxFit.cover,
          image: new NetworkImage(imgUrl),
        ),
      ),
      child: Container(
        margin: EdgeInsets.only(top: 500.0),
        child: Center(
          child: RaisedButton(
            color: Colors.white,
            child: Text("clicke here!"),
            onPressed: () {
              
            },
          )
        ),
      ),
    );
  }
}


4

3 回答 3

1

首先,您需要使用StatefulWidget对 UI 进行任何更改。但这里的第二个问题是图像在第一次加载后从缓存加载是相同的 URL。

只要您在上下文中使用相同的 URL,图像就会从缓存中加载。关于 upspash URL,您可以通过在按下按钮的 URL 末尾添加一些内容来调整一些值。

这是小部件


class MyWidgetsBinding extends WidgetsFlutterBinding {
  @override
  ImageCache createImageCache() => MyImageCache();
}

class _BackgroundImgDemoState extends State<BackgroundImgDemo> {
  String imgUrl1 = "https://unsplash.it/1440/3040?random";

  int count = 0;

  @override
  Widget build(BuildContext context) {
    return Container(
      decoration: BoxDecoration(
        image: new DecorationImage(
          fit: BoxFit.cover,
          image: new NetworkImage(
            "${imgUrl1}$count",
          ),
        ),
      ),
      child: Container(
        margin: EdgeInsets.only(top: 500.0),
        child: Center(
            child: RaisedButton(
          color: Colors.white,
          child: Text("clicke here!"),
          onPressed: () async {
            print("clear cache");
            setState(() {
              count++;
            });
          },
        )),
      ),
    );
  }
}

您也可以尝试cached_network_image维护缓存。

于 2021-09-16T17:40:35.787 回答
1

我也是一个非常初学者,我试图解决你的问题。我的方法是

  1. 将无状态小部件更改为有状态小部件
  2. 使用 NetworkImage 变量 showImg 传递给图像小部件
  3. 创建一个函数 updateUI 将刷新图像以显示
  4. 从 onPressed 函数调用 updateUI

但这似乎也不起作用。跟随线程知道如何做到这一点

import 'package:flutter/material.dart';

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    // TODO: implement build
    return MaterialApp(
      title: 'Welcome to Flutter',
      theme: new ThemeData(
        brightness: Brightness.light,
      ),
      home: new Scaffold(
          appBar: new AppBar(
            title: new Text("Welcome to Flutter"),
          ),
          body: BackgroundImgDemo()),
    );
  }
}

class BackgroundImgDemo extends StatefulWidget {
  @override
  State<BackgroundImgDemo> createState() => _BackgroundImgDemoState();
}

class _BackgroundImgDemoState extends State<BackgroundImgDemo> {
  final String imgUrl = "https://unsplash.it/1440/3040?random";
  NetworkImage showImg = NetworkImage("https://unsplash.it/1440/3040?random");

  void updateUI() {
    setState(() {
      showImg = NetworkImage(imgUrl);
    });
  }

  @override
  Widget build(BuildContext context) {
    return Container(
      decoration: BoxDecoration(
        image: DecorationImage(
          fit: BoxFit.cover,
          image: showImg,
        ),
      ),
      child: Container(
        margin: EdgeInsets.only(top: 500.0),
        child: Center(
          child: RaisedButton(
            color: Colors.white,
            child: const Text("click here!"),
            onPressed: () => updateUI(),
          ),
        ),
      ),
    );
  }
}


于 2021-09-16T17:34:48.153 回答
1

解决方案很简单,因为 URL 永远不会改变 Flutter 假定图像是相同的并从缓存中加载它。要解决此问题,您只需在每次单击按钮时提供不同的 URL。为此,您必须将随机值传递给 URL。

"https://unsplash.it/1440/3040?random" + "#v=${DateTime.now().microsecondsSinceEpoch}"

# 之后的所有内容都将被忽略,因此添加的随机值无关紧要,但它可以让构建器知道 URL 已更改。您可以在 setState 中传递此 URL 以使用新 URL 进行重建。使用这种方法,您根本不必创建任何函数。

类 BackgroundImgDemo

class BackgroundImgDemo extends StatefulWidget {
  const BackgroundImgDemo({Key? key}) : super(key: key);

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

class _BackgroundImgDemoState extends State<BackgroundImgDemo> {
  String imgUrl = "https://unsplash.it/1440/3040?random";

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Container(
        decoration: BoxDecoration(
          image: DecorationImage(
            fit: BoxFit.cover,
            image: NetworkImage(imgUrl),
          ),
        ),
        child: Container(
          margin: const EdgeInsets.only(top: 500.0),
          child: Center(
            child: ElevatedButton(
                onPressed: () {
                  setState(() {
                    imgUrl = "https://unsplash.it/1440/3040?random"
                        "#v=${DateTime.now().microsecondsSinceEpoch}";
                  });
                },
                child: const Text('Click Here!')),
          ),
        ),
      ),
    );
  }
}
于 2021-09-16T18:46:54.447 回答