Ned Bayne-Powell
Ned Bayne-Powell

Reputation: 191

How to change images using the Provider Package in Flutter

Problem: I click the button 'do something' and the image can't seem to change from 'hello' to 'goodbye'. The error coming back is

'Error: The argument type 'Image' can't be assigned to the parameter type 'String'.

Is it possible to change the String into an image so it will read the image and display it on the screen?

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

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Provider<MyModel>(//                              <--- Provider
      create: (context) => MyModel(),
      child: Consumer<MyModel>( //                           <--- MyModel Consumer
          builder: (context, myModel, child) {
            return ValueListenableProvider<Image>.value( // <--- ValueListenableProvider
              value: myModel.someValue,
              child: MaterialApp(
                home: Scaffold(
                  appBar: AppBar(title: Text('My App')),
                  body: Row(
                    mainAxisAlignment: MainAxisAlignment.center,
                    children: <Widget>[

                      Flexible(
                        child: Container(
                            padding: const EdgeInsets.all(20),
                            color: Colors.green[200],
                            child: Consumer<MyModel>( //       <--- Consumer
                              builder: (context, myModel, child) {
                                return RaisedButton(
                                  child: Text('Do something'),
                                  onPressed: (){
                                    myModel.doSomething();
                                  },
                                );
                              },
                            )
                        ),
                      ),

                      Flexible(
                        child: Container(
                          padding: const EdgeInsets.all(35),
                          color: Colors.blue[200],
                          child: Consumer<Image>(//           <--- String Consumer
                            builder: (context, myValue, child) {
                              return Image.asset(myValue);
                            },
                          ),
                        ),
                      ),

                    ],
                  ),
                ),
              ),
            );
          }),
    );
  }
}

class MyModel { //                                             <--- MyModel
  ValueNotifier<Image> someValue = ValueNotifier(Image.asset('images/hello.png')); // <--- ValueNotifier
  void doSomething() {
    someValue.value = Image.asset('images/goodbye.png');
    print(someValue.value);
  }
}

Upvotes: 0

Views: 1142

Answers (1)

Maqcel
Maqcel

Reputation: 509

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

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

class MyApp extends StatelessWidget {

  @override
  Widget build(BuildContext context) {
    return Provider<MyModel>(
      //                              <--- Provider
      create: (context) => MyModel(),
      child:
          Consumer<MyModel>(//                           <--- MyModel Consumer
              builder: (context, myModel, child) {
        return ValueListenableProvider<Image>.value(
          // <--- ValueListenableProvider
          value: myModel.someValue,
          child: MaterialApp(
            home: Scaffold(
              appBar: AppBar(title: Text('My App')),
              body: Row(
                mainAxisAlignment: MainAxisAlignment.center,
                children: <Widget>[
                  Flexible(
                    child: Container(
                        padding: const EdgeInsets.all(20),
                        color: Colors.green[200],
                        child: Consumer<MyModel>(
                          //       <--- Consumer
                          builder: (context, myModel, child) {
                            return RaisedButton(
                              child: Text('Do something'),
                              onPressed: () {
                                myModel.doSomething();
                              },
                            );
                          },
                        )),
                  ),
                  Flexible(
                    child: Container(
                      padding: const EdgeInsets.all(35),
                      color: Colors.blue[200],
                      child: Consumer<Image>(
                        //           <--- String Consumer
                        builder: (context, myValue, child) {
                          return myValue; //                         <--- **Change** 
                        },
                      ),
                    ),
                  ),
                ],
              ),
            ),
          ),
        );
      }),
    );
  }
}

class MyModel {
  //                                             <--- MyModel
  ValueNotifier<Image> someValue =
      ValueNotifier(Image.asset('images/hello.png')); // <--- ValueNotifier
  void doSomething() { //                         <--- **Change** 
    if (someValue.value.toString() ==
        Image.asset('images/hello.png').toString()) {
      someValue.value = Image.asset('images/goodbye.png');
    } else if (someValue.value.toString() ==
        Image.asset('images/goodbye.png').toString()) {
      someValue.value = Image.asset('images/hello.png');
    }
  }
}

myValue is already an image so you don't need to open it again from Image.asset also added feature to change image back and forth for your doSomething() function

Upvotes: 1

Related Questions