Home > Blockchain >  Change random background image by clicking a button flutter (dart)
Change random background image by clicking a button flutter (dart)

Time:03-20

I have a list of images, and a function that picks an image from that list randomly:

AssetImage imagePicker() {
    Random randomNumberGen = Random();
    int index = randomNumberGen.nextInt(bgImgList.length);
    return AssetImage(bgImgList[index]);
}

And I want a button that when clicking it will call this function and refresh the screen.

floatingActionButton: FloatingActionButton(
    onPressed: () { imagePicker(); },
    child: const Text(
      'change picture' ,
      textAlign: TextAlign.center,
    ),

The issue is the function is called, but the widget i have is not refreshing so the picture doesn't change

this is the widget code:

Widget build(BuildContext context) {
return Scaffold(
  appBar: AppBar(
    title: const Text('Israel Geography'),
    centerTitle: true,
    backgroundColor: Colors.blue[900],
  ),
  body: Center(
      child: Container(
        decoration: BoxDecoration(
          image: DecorationImage(
              image: imagePicker(),
              fit: BoxFit.cover
          ),
        ),
      )
  ),
  floatingActionButton: FloatingActionButton(
    onPressed: () { imagePicker(); },
    child: const Text(
      'change picture' ,
      textAlign: TextAlign.center,
    ),
  ),
);

}

CodePudding user response:

You need the state for a random image. StatefulWidget is one way to accomplish that.

class ImagePicker {
  static Image random() {
    return Image.network('https://picsum.photos/500/300?andom=${DateTime.now().millisecondsSinceEpoch}');
  }
}

class ImagePickerWidget extends StatefulWidget {
  const ImagePickerWidget();

  @override
  State<ImagePickerWidget> createState() => _ImagePickerWidgetState();
}

class _ImagePickerWidgetState extends State<ImagePickerWidget> {
  Image _random = ImagePicker.random();

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Center(child: _random),
      floatingActionButton: FloatingActionButton(
        onPressed: () => setState(() => _random = ImagePicker.random()),
        child: const Icon(Icons.refresh),
      ),
    );
  }
}

If you want to keep a widget stateless, provider is one way to that. See Simple app state management for details.

CodePudding user response:

Technically, you are calling the imagePicker() method twice, and there is also no state that is holding the final picked image.

Also, this makes the screen not static anymore. The displayed image is changing on each button click, so there is dynamic information in your UI now, so you need to convert your Stateless widget into a Stateful one so you can do setState() whenever the visible information changes.

So after converting to Stateful, your State class should have a variable like

 AssetImage pickedImage = AssetImage(...); // a default image

And in your imagePicker() method, you can assign the pickedImage var with the chosen image instead of returning it.

AssetImage imagePicker() {
    Random randomNumberGen = Random();
    int index = randomNumberGen.nextInt(bgImgList.length);
    // this will rebuild your UI
    setState(() {
       pickedImage = AssetImage(bgImgList[index]);
    });
}

And in your widget, instead of this:

image: imagePicker(),

Do this:

image: pickedImage,

And every time on button click, you pick a new image, rebuild the UI because of setState and now pickedImage will be pointing to another image.

  • Related