Search code examples
arraysflutterlistviewdartsharedpreferences

How do I add an item to a dynamic-list, using a button, to another screen with the list?


I'm not too familiar with flutter and coding in general yet. I'm also very new here so I apologize for any mistakes I might have done when posting a quesiton. Also, in case it's needed, I use android studio.
To be more descriptive, I wanna use sharedPreferences to save data taken from 4 Textfields from the 1stScreen as an array and add them to the list on the 2ndScreen. A list that has nothing yet and if the data from the 1st screen is saved, the list then shows 1 item containing the data saved.
Here's my mess of a code:

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

class ListProvider extends ChangeNotifier {
  List<String> litems = List<String>();

  List<String> get Items =>
      this.litems;

  set logList(List<String> value) {
    litems = value;
    notifyListeners();
  }
}
void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(

        primarySwatch: Colors.blue,
      ),
      home: MyHomePage(title: 'Flutter Demo Home Page'),
    );
  }
}

class MyHomePage extends StatefulWidget {
  MyHomePage({Key key, this.title}) : super(key: key);
  final String title;

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

class _MyHomePageState extends State<MyHomePage> with ChangeNotifier {
  TextEditingController firstname = TextEditingController();
  TextEditingController lastname = TextEditingController();
  TextEditingController birthday = TextEditingController();
  TextEditingController address = TextEditingController();
  //


  String data = "";
  String data1 = "";
  String data2 = "";
  String data3 = "";
  String firstname1 = "f";
  String lastname1 = "l";
  String birthday1 = "";
  String address1 = "";



  Future<bool>saveData() async{
    SharedPreferences preferences = await SharedPreferences.getInstance();
    return await preferences.setString(firstname1, firstname.text);
  }
  Future<bool>saveData1() async{
    SharedPreferences preferences1 = await SharedPreferences.getInstance();
    return await preferences1.setString(lastname1, lastname.text);
  }
  Future<bool>saveData2() async{
    SharedPreferences preferences = await SharedPreferences.getInstance();
    return await preferences.setString(birthday1, birthday.text);
  }
  Future<bool>saveData3() async{
    SharedPreferences preferences1 = await SharedPreferences.getInstance();
    return await preferences1.setString(address1, address.text);
  }

///////////

  Future<String> loadData() async{
    SharedPreferences preferences = await SharedPreferences.getInstance();
    return preferences.getString(firstname1);
  }
  Future<String> loadData1() async{
    SharedPreferences preferences2 = await SharedPreferences.getInstance();
    return preferences2.getString(lastname1);
  }
  Future<String> loadData2() async{
    SharedPreferences preferences = await SharedPreferences.getInstance();
    return preferences.getString(birthday1);
  }
  Future<String> loadData3() async{
    SharedPreferences preferences2 = await SharedPreferences.getInstance();
    return preferences2.getString(address1);
  }


  setData(){
    loadData().then((value){
      setState(() {
        data = value;
      });
    });
  }
  setData1(){
    loadData1().then((value){
      setState(() {
        data1 = value;
      });
    });
  }
  setData2(){
    loadData2().then((value){
      setState(() {
        data2 = value;
      });
    });
  }
  setData3(){
    loadData3().then((value){
      setState(() {
        data3 = value;

      });
    });
  }

  add(screen2){
    screen2.litems.add(data);
    notifyListeners();
    setState(() {

    });
  }




  @override
  Widget build(BuildContext context) {

    return Scaffold(
      appBar: AppBar(
        title: Text(widget.title),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.spaceAround,
          children: <Widget>[
            TextField(
              controller: firstname,
              decoration: InputDecoration(
                  hintText: "FIRST NAME"
              ),
            ),
            TextField(
              controller: lastname,
              decoration: InputDecoration(
                  hintText: "LAST NAME"
              ),
            ),
            TextField(
              controller: birthday,
              decoration: InputDecoration(
                  hintText: "BIRTHDAY"
              ),
            ),
            TextField(
              controller: address,
              decoration: InputDecoration(
                  hintText: "ADDRESS"
              ),
            ),
            RaisedButton(
              onPressed: (){
                saveData();
                saveData1();
                saveData2();
                saveData3();
                setData();
                setData1();
                setData2();
                setData3();
                add(screen2());
              },
              child: Text("ADD"),
            ),
            RaisedButton(
              onPressed: (){
                Navigator.push(
                  context,
                  MaterialPageRoute(builder: (context) => screen2()),
                );
              },
              child: Text("SHOW ALL"),
            ),
          ],
        ),
      ),
    );
  }
}

This is the second screen I need to access the list from.

Code snippet taken from this

    class screen2 extends StatefulWidget {
      @override
      State createState() => new DyanmicList();
    }

    class DyanmicList extends State<screen2> with ChangeNotifier {
      List<String> litems = [];




      final TextEditingController eCtrl = new TextEditingController();
      @override
      Widget build (BuildContext ctxt) {
        return new Scaffold(
            appBar: new AppBar(title: new Text("Screen2"),),
            body: new Column(
              children: <Widget>[
                new TextField(
                  controller: eCtrl,
                  onSubmitted: (text) {
                    litems.add(text);
                    eCtrl.clear();
                    setState(() {});
                  },
                ),
                new Expanded(
                    child: new ListView.builder
                      (
                        itemCount: litems.length,
                        itemBuilder: (BuildContext ctxt, int Index) {
                          return new Text(litems[Index]);
                        }
                    )
                )
              ],
            )
        );
      }
    }


Solution

  • In screen 1,when submit button is pressed, add the 4 info into a list and store to sharedPreferences.

    Screen1

    var list = List<Info>();
            ...
    list.add(Info(firstName,lastName,birthday,address));
    prefs.storeList(json.encode(list));
    

    Info

    class Info {
      String firstName;
      String lastName;
      String birthday;
      String address;
    
      Info(this.firstName, this.lastName,this.birthday,this.address);
    }
    

    SharedPreferences

         Future storeList(String info) async {
            SharedPreferences prefs = await SharedPreferences.getInstance();
            prefs.setString(INFO, info);
          }
        
       Future getListFromSharedPreferences() async {
        SharedPreferences prefs = await SharedPreferences.getInstance();
        return prefs.getString(INFO);
      }
    

    Screen 2

    In screen 2 widget build, use FutureBuilder to get the list from sharedPreferences.

     FutureBuilder(
            future: sharedPreferences.getListFromSharedPreferences(),
            builder: (context, snapshot) {
              if (snapshot.hasData) {
                return ListView.builder(
                    itemCount: (jsonDecode(snapshot.data)).length,
                    itemBuilder: (BuildContext ctxt, int index) {
                      return new Text(jsonDecode(snapshot.data)[index]);
                    });
              } else {
                return Text("No data");
              }
            });