Home > OS >  Flutter : I want to change an image when you tap the image, and others are not affected by the tap
Flutter : I want to change an image when you tap the image, and others are not affected by the tap

Time:10-22

I am creating a simple app in Flutter. There are 7 images on 1 screen. I need a function that you can change an image when you tap one of the images. However, now when I tap an image, the other 6 images are also changed. I made a variable "isReal" to put into buildButton() and "isReal" would be switched true and false in the For statement which switch "isReal" in buildButton(). But, that did not work. Could you give me some advice on this problem? Thank you.

import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:audioplayers/audioplayers.dart';

class Screen extends StatefulWidget {
  @override
  _ScreenState createState() => _ScreenState();
}

class _ScreenState extends State<Screen> {
  bool isReal = true;
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
        debugShowCheckedModeBanner: false,
        home: Scaffold(
            backgroundColor: Colors.teal[100],
            // appBar: AppBar(
            //     title: Text('AnimalSounds'), backgroundColor: Colors.teal),
            body: SafeArea(
              child: Column(
                crossAxisAlignment: CrossAxisAlignment.stretch,
                children: <Widget>[
                  buildButton('cat.mp3', Colors.red, 'images/cat.png',
                      'images/cat_real.jpg'),
                  Expanded(
                      child: Row(
                          crossAxisAlignment: CrossAxisAlignment.stretch,
                          children: <Widget>[
                        buildButton('dog.mp3', Colors.yellow, 'images/dog.png',
                            'images/cow.png'),
                        buildButton('cow.mp3', Colors.orange, 'images/cow.png',
                            'images/dog.png'),
                      ])),
                  Expanded(
                      child: Row(
                          crossAxisAlignment: CrossAxisAlignment.stretch,
                          children: <Widget>[
                        buildButton('pig.mp3', Colors.green, 'images/pig.png',
                            'images/elephant.png'),
                        buildButton('elephant.mp3', Colors.teal,
                            'images/elephant.png', 'images/rooster.png'),
                        buildButton('rooster.mp3', Colors.blue,
                            'images/rooster.png', 'images/pig.png'),
                      ])),
                  Expanded(
                      child: Column(
                    crossAxisAlignment: CrossAxisAlignment.stretch,
                    children: <Widget>[
                      buildButton('goat.mp3', Colors.purple, 'images/goat.jpg',
                          'images/pig.png'),
                    ],
                  )),
                ],
              ),
            )));
  }

  Expanded buildButton(sound, color, simpleImage, realImage) {
    return Expanded(
        child: FlatButton(
      onPressed: () {
        setState(() {
          isReal = !isReal;
        });
        final player = AudioCache();
        player.play(sound);
      },
      color: color,
      child: isReal ? Image.asset(simpleImage) : Image.asset(realImage),
    ));
  }
}

CodePudding user response:

Ok, you have variable isReal that is the same for entire class (i.e. each button use the same variable). So when you change it's value by tapping on one button it affects all other buttons as well.

To solve this issue I would recommend to move button implementation into a separate Statefull widget. This way you can keep your Screen class as Stateless.

CodePudding user response:

You can use Random class from dart:math to generate the next random image. Exemple :

  int imageNumber = 1;
  void updateImage() {
    setState(() {
  //Random.nextInt(n) returns random integer from 0 to n-1
      imageNumber = Random().nextInt(7)   1;
    });
  }
  @override
  Widget build(BuildContext context) {
    return Center(
      child: Expanded(
        child: Padding(
          padding: const EdgeInsets.all(50.0),
          child: FlatButton(
            child: Image.asset('images/dice$imageNumber.png'),
            onPressed: () {
              updateImage();
            },
          ),
        ),
      ),
    );
  }
  • Related