【问题标题】:Why isn't the image changing using the Provider Package?为什么使用提供程序包不改变图像?
【发布时间】:2020-10-23 18:12:10
【问题描述】:

我正在使用 Flutter 上的提供程序包,但无法弄清楚为什么当我调用 mymodel.image 时它没有更改背景图像。它应该访问 MyModal 类并将现有图像:Image.asset('images/background_image.jpeg', fit: BoxFit.fill) 更改为 SmallImage 屏幕中的图像。

mymodel.image = Image.asset('images/hello_image.png', fit: BoxFit.fill);

替换主页上的背景图片。

主页屏幕

import 'package:flutter/material.dart';
import 'package:flutter_app_background/small_images.dart';
import 'package:flutter/cupertino.dart';
import 'package:provider/provider.dart';


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


class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return ChangeNotifierProvider<MyModel>(
      create: (context) => MyModel(),
      child: MaterialApp(
        title: 'Title',
        home: HomePage(),
      ),
    );
  }
}

class HomePage extends StatelessWidget {

  @override
  Widget build(BuildContext context) {
      return Scaffold(
        extendBodyBehindAppBar: true,
        appBar: AppBar(
          title: Text('Background Image', style: TextStyle(
              color: Colors.black,
              fontSize: 16,
              fontWeight: FontWeight.bold),
          ),
          iconTheme: IconThemeData(color: Colors.white),
          actions: <Widget>[
            IconButton(
              icon: Icon(Icons.settings, color: Colors.black,),
              onPressed: () {
                Navigator.push(
                  context,
                  MaterialPageRoute(builder: (context) => SmallImages()),
                );
              },
            ),
          ],
          backgroundColor: Colors.transparent,
          elevation: 0.0,
        ),
        body: Stack(
          children: <Widget>
          [
            Positioned.fill(
              child: GestureDetector(
                child: Consumer<MyModel>(
                  builder: (context, myModel, child) {
                return myModel.image = Image.asset('images/background_image.jpeg', fit: BoxFit.fill);
                  },
                ),
              ),
            ),
          ],
        ),
      );
    }
}

class MyModel extends ChangeNotifier {
  Image _image;
  set image(Image value) {
    _image = value;
    notifyListeners();
  }
  Image get image => _image;

}

小图像屏幕

import 'package:flutter/material.dart';
import 'package:flutter_app_background/main.dart';
import 'package:provider/provider.dart';


class SmallImages extends StatefulWidget {
  static int tappedGestureDetector = 1;

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

class _SmallImagesState extends State<SmallImages> {
  List<bool> isSelected;

  void initState() {
    isSelected = [true, false, false, false, false, false, false, false, false];
    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    final mymodel = Provider.of<MyModel>(context,listen:false); //default for listen is `true`
    return Scaffold(
    appBar: AppBar(
            title: Text('Small Image', style: TextStyle(
                color: Colors.black, fontSize: 16, fontWeight: FontWeight.bold),
            ),
            iconTheme: IconThemeData(color: Colors.white),
            actions: <Widget>[
              IconButton(
                icon: Icon(Icons.arrow_left, color: Colors.black,),
                onPressed: () {
                  Navigator.pop(
                    context,
                    MaterialPageRoute(builder: (context) => HomePage()),
                  );
                },
              ),
            ],
            backgroundColor: Colors.transparent,
            elevation: 0.0,
          ),
          body: Material(
            child: GestureDetector(
              child: MaterialApp(
                  builder: (context, snapshot) {
                    return GridView.count(
                      crossAxisCount: 1,
                      childAspectRatio: 1.0,
                      padding: const EdgeInsets.all(4.0),
                      mainAxisSpacing: 0.0,
                      crossAxisSpacing: 0.0,
                      children: [
                        GridView(
                          gridDelegate:
                          SliverGridDelegateWithFixedCrossAxisCount(crossAxisCount: 3,
                            childAspectRatio: MediaQuery
                                .of(context)
                                .size
                                .width /
                                (MediaQuery
                                    .of(context)
                                    .size
                                    .height / 2),
                          ),
                          children: [
                                 GestureDetector(
                                onTap: () {
                                      // return myValue;
                                  setState(() {
                                    SmallImages.tappedGestureDetector = 1;
                                  });
                                  return mymodel.image  = Image.asset('images/hello_image.png', fit: BoxFit.fill);
                                  print('hi');
                                },
                                child: Container(
                                  height: 100,
                                  width: 107,
                                  decoration: BoxDecoration(border: SmallImages
                                      .tappedGestureDetector == 1
                                      ? Border.all(
                                      color: Color(0xff2244C7), width: 1.0)
                                      : Border
                                      .all(color: Colors.transparent,),),
                                  child: Image.asset(
                                    'images/nightsky_image.png',
                                  ),
                                ),
                                ),
                            Consumer<MyModel>(
                              builder: (context, myModel, child) {
                                return GestureDetector(
                                  onTap: () {
                                    setState(() {
                                      SmallImages.tappedGestureDetector = 2;
                                    }); // <-- replaced 'tapped' and 'other'
                                  },
                                  child: Container(
                                    height: 100,
                                    width: 107,
                                    decoration: BoxDecoration(border: SmallImages
                                        .tappedGestureDetector == 2
                                        ? Border.all(
                                        color: Color(0xff2244C7), width: 1.0)
                                        : Border
                                        .all(color: Colors.transparent,),),
                                    child: Image.asset(
                                      'images/own_image.png',
                                    ),
                                  ),
                                );
                              },
                            ),
                            Consumer<MyModel>(
                              builder: (context, myModel, child) {
                                return GestureDetector(
                                  onTap: () {
                                    setState(() {
                                      SmallImages.tappedGestureDetector = 3;
                                    }); // <-- replaced 'tapped' and 'other'
                                  },
                                  child: Container(
                                    height: 100,
                                    width: 107,
                                    decoration: BoxDecoration(border: SmallImages
                                        .tappedGestureDetector == 3
                                        ? Border.all(
                                        color: Color(0xff2244C7), width: 1.0)
                                        : Border
                                        .all(color: Colors.transparent,),),
                                    child: Image.asset(
                                      'images/iceland_image.png',
                                    ),
                                  ),
                                );
                              },
                            ),
                          ].toList(),
                        ),
                      ],
                    );
                  }),
            ),
          ),
        );
  }
}

【问题讨论】:

    标签: image class flutter state flutter-onpressed


    【解决方案1】:

    当图像发生变化时,您必须在模型中调用 notifyListeners,否则 changenotifierprovider 将不知道它需要重建。

    一种方法是使用 getter 和 setter 包装图像字段,并在更新基础字段后调用 setter 中的 notifyListeners。

    var Image _image;
    set image(Image value) {
      _image = value;
      notifyListeners();
    }
    Image get image => _image;
    

    【讨论】:

    • 感谢您的回答,我在这里调用了它,但它仍然无法正常工作:class MyModel extends ChangeNotifier { Image image = Image.asset('images/background_image.jpeg', fit: BoxFit.填);通知监听器(); }
    • 我在发布的代码中的任何地方都看不到对 notifyListeners 的调用。你能更新它以包含它吗?
    • 是的,我已经添加进去了
    • 好吧,我想你不太明白代码。您向模型添加了一个调用 notifyListeners 的方法,但仍然永远不会调用 onChange 方法。当您为图像设置新值时,您需要调用 notifyListeners。一种方法是使用 getter 和 setter 包装图像字段,并在更新基础字段后调用 setter 中的 notifyListeners。
    • 嗨皮特,我已经用你的答案更新了代码,你能不能最后一次看一下,因为我还在改变图像?
    猜你喜欢
    • 2021-02-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-11-19
    • 1970-01-01
    • 2012-06-12
    • 1970-01-01
    • 2022-01-05
    相关资源
    最近更新 更多