Search code examples
stringfluttericonssharedpreferences

save string and associated icon with shared prefs


I'm currently using the shared preferences to save a string list. Every time the page is opened, for every string entry from the list I create a list tile inside a list view. But now I don't want to only save the string, I even want to save an icon with it. But I have absolutely no idea on how to solve this

Here is my current code:

import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'package:trainings_app/widgets/alertbox_widget.dart';
import 'package:trainings_app/widgets/team_widget.dart';

class TeamScreen extends StatefulWidget {
  @override
  _TeamScreenState createState() => _TeamScreenState();
}

class _TeamScreenState extends State<TeamScreen> {
  late SharedPreferences sharedPreferences;
  List<String> teams = [];

  IconData? currentIcon;

  @override
  void initState() {
    tryFetchData();
    super.initState();
  }

  void tryFetchData() async {
    sharedPreferences = await SharedPreferences.getInstance();
    if (!sharedPreferences.containsKey('teams')) {
      sharedPreferences.setStringList('teams', []);
      return;
    }
    teams = sharedPreferences.getStringList('teams') as List<String>;
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: ListView.builder(
        itemCount: teams.length,
        itemBuilder: (context, index) {
          return Team(
            teams[index],
            Icon(currentIcon),
            () => removeTeam(teams[index]),
          );
        },
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: () {
          newTeam();
        },
        child: Icon(
          CupertinoIcons.add,
        ),
      ),
    );
  }

  void newTeam() {
    showDialog<Alertbox>(
      context: context,
      builder: (BuildContext context) {
        return Alertbox('Namen auswählen:', addTeam);
      },
    );
  }

  void addTeam(String name, IconData? icon) {
    if (name.isNotEmpty) {
      setState(() {
        currentIcon = icon;
        teams.add(name);
      });
    }

    Navigator.pop(context);
    sharedPreferences.setStringList('teams', teams);
  }

  void removeTeam(String name) {
    setState(() {
      teams.remove(name);
    });

    sharedPreferences.setStringList('teams', teams);
  }
}

class Team extends StatelessWidget {
  final String name;
  final Icon icon;
  final Function remove;
  const Team(this.name, this.icon, this.remove);

  @override
  Widget build(BuildContext context) {
    return Container(
      padding: EdgeInsets.symmetric(horizontal: 22),
      child: ListTile(
        leading: Icon(icon.icon),
        contentPadding: EdgeInsets.symmetric(vertical: 8.0),
        title: Text(
          name,
          style: TextStyle(
            fontSize: 18.0,
            fontWeight: FontWeight.w600,
          ),
        ),
        trailing: IconButton(
          icon: Icon(CupertinoIcons.delete),
          onPressed: () => remove(),
        ),
        onTap: () {
          Navigator.push(context,
              MaterialPageRoute(builder: (context) => TeamWidget(name, icon)));
        },
      ),
    );
  }
}

Solution

  • you can use each Icon specific id instead of IconData and store it as a List of Json:

    Json.encode({title:"test", icon:61668}
    

    and then save it in sharedPref. after that you can recall it as follows:

    Icon(IconData(**YOUR SELECTED ID**, fontFamily: 'MaterialIcons'));
    

    check the id of each icon here: link


    The other solution can be using images instead of icons! or using this site to convert image to font icon and use it as follows:

    Icon(IconData(int.parse('0x${e90a}',
        fontFamily: 'family name given in the link above'));