Home > Software design >  How to change background using conditions and save it in Flutter/Dart?
How to change background using conditions and save it in Flutter/Dart?

Time:07-02

I have a code that changes text when the button is clicked:

// New Game route
class NewGameRoute extends StatelessWidget {
  const NewGameRoute({key});

  @override
  Widget build(BuildContext context) {
    return const MaterialApp(
      debugShowCheckedModeBanner: false,
      title: 'New Game',
      home: ListFromCSV1(),
    );
  }
}

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

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

class _ListFromCSVState1 extends State<ListFromCSV1> {
  List<List<dynamic>> _listData = [
    [""]
  ];
  int _listCount = 0;
  bool _isFirstLoad = true;

  @override
  initState() {
    _loadCSV();
  }

  // This function is only triggered at init, so we only load csv once
  void _loadCSV() async {
    String _rawData = await rootBundle.loadString("files/Text.csv");
    _listData = const CsvToListConverter().convert(_rawData);
  }

  // This function is triggered when my button is pressed
  void _nextCSV() {
    setState(() {
      _listData = _listData;
      _listCount < _listData.length - 1
          ? _isFirstLoad ? _isFirstLoad = false
          : _listCount  
          : _listCount;
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('New Game'),
      ),
      body: Container(
        height: MediaQuery
            .of(context)
            .size
            .height,
        decoration: BoxDecoration(
            image: DecorationImage(
                  image: AssetImage('files/main.jpg'), fit: BoxFit.cover)),
        child: Column(
          mainAxisSize: MainAxisSize.min,
          children: <Widget>[
            // const SizedBox(height: 30),
            ClipRRect(
              borderRadius: BorderRadius.circular(4),
              child: Stack(
                children: <Widget>[
                  Positioned.fill(
                    child: Container(
                      decoration: const BoxDecoration(
                          image: DecorationImage(
                              image: AssetImage('files/sheet.jpg'),
                              fit: BoxFit.cover)),
                    ),
                  ),
                  Text(_listData[_listCount][0]),
                ],
              ),
            ),
            // const SizedBox(height: 30),
            ClipRRect(
              borderRadius: BorderRadius.circular(4),
              child: Row(
                mainAxisAlignment: MainAxisAlignment.spaceAround,
                children: [
                  TextButton(
                    style: TextButton.styleFrom(
                      padding: const EdgeInsets.all(16.0),
                      primary: Colors.white,
                      textStyle: const TextStyle(fontSize: 20),
                    ),
                    // onPressed: () {},
                    onPressed: _nextCSV,

                    child: const Text('OK'),
                  ),
                  TextButton(
                    style: TextButton.styleFrom(
                      padding: const EdgeInsets.all(16.0),
                      primary: Colors.white,
                      textStyle: const TextStyle(fontSize: 20),
                    ),
                    onPressed: () {},
                    // onPressed: _nextCSV,

                    child: const Text('Hide'),
                  ),
                ],
              ),
            ),
            // const SizedBox(height: 30),
          ],
        ),
      ),
    );
  }
}

I need to do the same for pictures used as backgrounds. But there is a certain condition.

  1. By default, my user should see the picture that is specified in the code:

    image: AssetImage('files/main.jpg'), fit: BoxFit.cover)),

  2. Next, my user must click on the OK button and there are two options: 2.1 If _listData_listCount is empty, then the picture does not change. 2.2. If _listData_listCount is not empty (for example, images/02.jpg), then the user should see this picture.

  3. The path to the image my user sees should be saved so that the next time my user opens this app, he/she will see it.

Here is a small file for testing: FILE

Thanks in advance.

CodePudding user response:

i think you should add condition in the AssetImage like isListEmpty then it should be like this, and images/02.jpg in asset folder already. Use Shared Ppreferences to store that in local maybe

AssetImage( isListEmpty ? 'files/main.jpg' : 'images/02.jpg')

CodePudding user response:

Hope this helps.

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

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

class _ListFromCSVState extends State<ListFromCSV> {
  List<List<dynamic>> _listData = [
    [""]
  ];
  int _listCount = 0;
  bool _isFirstLoad = true;
  String assetPath = "assets/files/main.jpeg";

  @override
  void initState() {
    _loadCSV();
  }

  // This function is only triggered at init, so we only load csv once
  void _loadCSV() async {
    String rawData = await rootBundle.loadString("assets/files/Text.csv");
    _listData = const CsvToListConverter().convert(rawData);
    assetPath = _listData[_listCount][1] == "" ? "assets/files/main.jpeg" : _listData[_listCount][1];
  }

  // This function is triggered when my button is pressed
  void _nextCSV() {
    setState(() {
      _listData = _listData;
      _listCount < _listData.length - 1
          ? _isFirstLoad
              ? _isFirstLoad = false
              : _listCount  
          : _listCount;
      assetPath = _listData[_listCount][1] == "" ? assetPath : _listData[_listCount][1];
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('New Game'),
      ),
      body: Container(
        height: MediaQuery.of(context).size.height,
        decoration: BoxDecoration(
            image: DecorationImage(
                image: AssetImage("assets/files/sheet.jpeg"), fit: BoxFit.cover)),
        child: Column(
          mainAxisSize: MainAxisSize.min,
          children: <Widget>[
            // const SizedBox(height: 30),
            ClipRRect(
              borderRadius: BorderRadius.circular(4),
              child: Stack(
                children: <Widget>[
                  Positioned.fill(
                    child: Container(
                      decoration: BoxDecoration(
                          image: DecorationImage(
                              image: AssetImage(assetPath),
                              fit: BoxFit.cover)),
                    ),
                  ),
                  Text(_listData[_listCount][0]),
                ],
              ),
            ),
            // const SizedBox(height: 30),
            ClipRRect(
              borderRadius: BorderRadius.circular(4),
              child: Row(
                mainAxisAlignment: MainAxisAlignment.spaceAround,
                children: [
                  TextButton(
                    style: TextButton.styleFrom(
                      padding: const EdgeInsets.all(16.0),
                      primary: Colors.white,
                      textStyle: const TextStyle(fontSize: 20),
                    ),
                    // onPressed: () {},
                    onPressed: _nextCSV,
                    child: const Text('OK'),
                  ),
                  TextButton(
                    style: TextButton.styleFrom(
                      padding: const EdgeInsets.all(16.0),
                      primary: Colors.white,
                      textStyle: const TextStyle(fontSize: 20),
                    ),
                    onPressed: () {},
                    // onPressed: _nextCSV,
                    child: const Text('Hide'),
                  ),
                ],
              ),
            ),
            // const SizedBox(height: 30),
          ],
        ),
      ),
    );
  }
}

Do not forget to add the images pubsec.yaml file and in CSV mention the correct path.

  • Related