0

I am creating an app in flutter in which i can select the contacts from phone book , saving them in shared preferences and displaying contact list on main page UI. Every thing is working fine but i have to press the load button each time to show the updated list on UI . I want it to update automatically when i go back to main.dart page after selecting the contacts. how can i manage this state?

main.dart file :

import 'package:flutter/material.dart';
import 'package:mapstest/test_stuff/contact_model.dart';
import 'package:mapstest/test_stuff/google_maps.dart';
import 'package:mapstest/test_stuff/select_contacts.dart';
import 'package:mapstest/test_stuff/shared_pref.dart';
import 'package:mapstest/test_stuff/sms.dart';
import 'package:shared_preferences/shared_preferences.dart';

void main() {
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({Key? key}) : super(key: key);

  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: const MyHomePage(),
    );
  }
}

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

  @override
  State<MyHomePage> createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {


  SharedPref sharedPref = SharedPref();
  ContactModel modelLoad = ContactModel(
      displayName: 'saniya', phoneNumber: '324235 ');
  List _list = [];
  

  @override
  initState() {
    super.initState();
    // Add listeners to this clas
    // loadSharedPrefs();
  }


  loadSharedPrefs() async {
    try {
      _list.clear();
      print('in load shared pref-- getting keys ');
      final prefs = await SharedPreferences.getInstance();


      final keys = prefs.getKeys();


      print('now load shared pref ');
      for (String key in keys) {
        ContactModel user = ContactModel.fromJson(await sharedPref.read(key));
        _list.add(user);
      }
      setState(() {

      });
      print('done load shared pref ');
    }
    catch (Excepetion) {

    }
  }


  @override
  Widget build(BuildContext context) {
    return Scaffold(
        appBar: AppBar(
          title: const Text('Testing Stuff for FYP'),
          centerTitle: true,
        ),
        body: Column(
          children: [
            RaisedButton(
              onPressed: () {
                Navigator.push(context,
                    MaterialPageRoute(builder: (context) => GoogleMaps()));
              },
              child: const Text('View Google Maps'),
            ),
            RaisedButton(
              onPressed: () {
              //  Navigator.push(context,
                //    MaterialPageRoute(builder: (context) => ShareData()));
              },
              child: const Text('Share Over Apps'),
            ),
            RaisedButton(
              onPressed: () {
                Navigator.push(context,
                    MaterialPageRoute(builder: (context) => MySMS(list: _list,)));
              },
              child: const Text('SMS ALERT'),
            ),
            RaisedButton(
              onPressed: () {
                Navigator.push(context,
                    MaterialPageRoute(builder: (context) => Plugin1()));
              },
              child: const Text(''
                  'select contacts'),
            ),
            RaisedButton(
              onPressed: () async {
                await loadSharedPrefs();

              },
              child: Text('Load', style: TextStyle(fontSize: 20)),
            ),
            Expanded(
              child: _list.isNotEmpty ?
              ListView.builder(
                shrinkWrap: true,
                itemCount: _list.length,
                itemBuilder: (context, position) {
                  return ListTile(
                    leading: Icon(Icons.contacts),
                    title: Text(
                      _list[position].displayName.toString(),
                      style: TextStyle(
                        fontWeight: FontWeight.bold,
                      ),
                    ),
                    subtitle: Text(_list[position].phoneNumber.toString()) ,
                    trailing: IconButton(
                      icon: Icon(Icons.delete),
                      onPressed: () async {
                        print( _list[position].displayName.toString());
                        String key = _list[position].displayName.toString();
                        await deleteFromSharedPrefs(key);
                        deleteFromList(position);

                      },

                    ),


                  );

                },
              ) : Center(child: Text('No list items to show')),
            ),

          ],
        ));
  }


  void deleteFromList(int index) {
    print('deleting from list');
    _list.removeAt(index);
    print('deleted from list');

    setState(() {

    });

  }

  Future<void> deleteFromSharedPrefs(String key) async {
    print('deleting from SharedPref');
    final prefs = await SharedPreferences.getInstance();
    SharedPref sharedPref = SharedPref();
    sharedPref.remove(key);
    print('deleted from SharedPref');
  }


}

select_contacts.dart file:

//import 'package:contacts_test/main.dart';
//import 'package:contacts_test/shared_pref.dart';
import 'package:flutter/material.dart';
import 'package:fluttercontactpicker/fluttercontactpicker.dart';
import 'package:mapstest/test_stuff/shared_pref.dart';
import 'package:permission_handler/permission_handler.dart';

import 'contact_model.dart';



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

  @override
  State<Plugin1> createState() => _Plugin1State();
}

class _Plugin1State extends State<Plugin1> {
  SharedPref sharedPref = SharedPref();
  ContactModel model = ContactModel(displayName: ' ' , phoneNumber: ' ');
  List<ContactModel> _list = [];

  PhoneContact? _contact;

  String? _phoneContact;
  String? _name;
  int? _id;

  final Permission _permission = Permission.contacts;
  PermissionStatus _permissionStatus = PermissionStatus.denied;

  Future<PermissionStatus> _getContactPermission() async {
    _permissionStatus = await _permission.status;

    if (_permissionStatus != PermissionStatus.granted) {
      _permissionStatus = await _permission.request();
      return _permissionStatus;
    } else {
      return _permissionStatus;
    }
  }

  pickContact() async {

    PermissionStatus permissionStatus = await _getContactPermission();
    if (permissionStatus == PermissionStatus.granted) {
      final PhoneContact contact =
      await FlutterContactPicker.pickPhoneContact();


      _phoneContact = contact.phoneNumber?.number;
      _name = contact.fullName;


      //set into model
      model = ContactModel( displayName: _name.toString(), phoneNumber: _phoneContact.toString());

      await sharedPref.save(model.displayName, model);

      _list.add(model);
      setState(()  {

      });
    }
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
        appBar: AppBar(),
        body: Column(
          mainAxisAlignment: MainAxisAlignment.spaceAround,
          children: [

            RaisedButton(
              onPressed: () {
                pickContact();
              },
              child: Text('select contacts'),
            ),
            Expanded(
              child: _list.isNotEmpty ?
              ListView.builder(
                shrinkWrap: true,
                itemCount: _list.length,
                itemBuilder: (context, position) {
                  return ListTile(
                    leading: Icon(Icons.contacts),
                    title: Text(

                        _list[position].displayName.toString()
                    ),

                  );



                },
              ) : Center(child: Text('No list items to show')),
            ),



            //     Text(_phoneContact ?? "contact not selected" ),
            //    Text(_name ?? "name not selected" ),]
          ],
        ));
  }
}

shared_pref.dart file (separate class for shared preferences)

import 'package:shared_preferences/shared_preferences.dart';
import 'dart:convert';


class SharedPref {
  read(String key) async {
    final prefs = await SharedPreferences.getInstance();
    return json.decode(prefs.getString(key).toString());
  }

  save(String key, value) async {
    final prefs = await SharedPreferences.getInstance();
    prefs.setString(key, json.encode(value));
  }

  remove(String key) async {
    final prefs = await SharedPreferences.getInstance();
    prefs.remove(key);
  }

  clearData() async {
    final prefs = await SharedPreferences.getInstance();
    prefs.clear();
  }

}

contact_model.dart file (model class for contacts):

class ContactModel {
  int? id;
  String displayName;
  String phoneNumber;


  ContactModel({ this.id, required this.displayName, required this.phoneNumber});

  //setters
  set contactName(String dispName) {
    displayName = dispName;
  }

  set contactNumber(String num) {
    phoneNumber = num;
  }

  //getters
  String get contactName {
    return displayName;
  }

  String get contactNumber {
    return phoneNumber;
  }

  ContactModel.fromJson(Map<String, dynamic> json)
      : displayName = json['displayName'],
        phoneNumber = json['phoneNumber'];


  Map<String, dynamic> toJson() => {
    'displayName': displayName,
    'phoneNumber': phoneNumber,
  };



  @override
  String toString() {
    return 'Contact { name: $displayName, age: $phoneNumber}';
  }


}//class ends
sjDev
  • 41
  • 5
  • one thing, without setState UI doesnt update – Md. Yeasin Sheikh Jul 19 '22 at 18:27
  • yes i am using setState() in LoadsharedPref() method but for that i have to click on Load button then it is working. What i want it is to refresh without calling set State() just like we do using Provider Package. Can anyone help me how can i use Provider in this case? – sjDev Jul 19 '22 at 19:09
  • btw you;ve commented ` // loadSharedPrefs();` on initState – Md. Yeasin Sheikh Jul 19 '22 at 19:26

1 Answers1

0

Wait until a route is popped and then reload. Something like this:

RaisedButton(
  onPressed: () async {
    await Navigator.push(context, MaterialPageRoute(builder: (context) => Plugin1()));
    await loadSharedPrefs();
  },
...
),

See Return data from a screen for details.

user18309290
  • 5,777
  • 2
  • 4
  • 22