Home > Enterprise >  Content on screen multiplying every time, screen is being initialized (SQLite, flutter)
Content on screen multiplying every time, screen is being initialized (SQLite, flutter)

Time:10-17

The database rendered elements are multiplying on screen every time, I click off the screen and then back onto the screen.

Here is the code that is creating those elements on screen:

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

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

class _AlarmScreenState extends State<AlarmScreen> {

  AlarmHelper _alarmHelper = AlarmHelper();
  Future<List<AlarmInfo>>? _alarms;

  @override
  void deactivate() {
    super.deactivate();
  }


  @override
  void initState() {
    _alarmHelper.initializeDatabase().then((value) => print('------------dB initialized'));
    _alarms = _alarmHelper.getAlarm();
    super.initState();


  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      backgroundColor: Color(0xFF2D2F41),
      appBar: PreferredSize(preferredSize: Size.fromHeight(50),
          child: CustomAppBar("Alarm")),
      body: Column(
        mainAxisAlignment: MainAxisAlignment.center,
        children: <Widget> [
          Expanded(
            child: Padding(
              padding: EdgeInsets.symmetric(horizontal: 45, vertical: 10),
              child: FutureBuilder<List<AlarmInfo>>(
                future: _alarms,
                builder: (context, snapshot)
                {
                  if(snapshot.hasData){
                  return ListView(
                    children: snapshot.data!.map<Widget>((alarms) {
                      return Container(
                    margin: EdgeInsets.only(bottom: 32),
                    padding: EdgeInsets.symmetric(horizontal: 16, vertical: 8),
                    child: Column(
                      crossAxisAlignment: CrossAxisAlignment.start,
                      children: [
                        Row(
                          mainAxisAlignment: MainAxisAlignment.spaceBetween,
                          children: [
                            Row(
                              children: [
                                Icon(Icons.label, color: Colors.white, size:
                                24,),
                                SizedBox(width: 8,),
                                Text(alarms.title, style: TextStyle(color:
                                Colors.white, fontFamily: 'avenir'),),
                              ],
                            ),
                            Switch(value: alarms.isPending == 1 ? true : false, onChanged: (bool value){},
                              activeColor: Colors.white,)
                          ],
                        ),
                        Text('Mon-Fri', style: TextStyle(color:
                        Colors.white, fontFamily: 'avenir'),),
                        Row(
                          mainAxisAlignment: MainAxisAlignment.spaceBetween,
                          children: [
                            Text( alarms.dateTime.hour.toString().padLeft(2, "0")   ":"   alarms.dateTime.minute.toString().padLeft(2, "0") , style: TextStyle(color:
                            Colors.white, fontFamily: 'avenir',
                                fontWeight: FontWeight.w700,
                                fontSize: 24),),
                            IconButton(onPressed: (){
                              _alarmHelper.deleteAlarm(alarms.id);
                              setState(() {

                              });
                            }, icon: Icon(Icons.delete, color: Colors.white, size: 24,))
                          ],
                        ),
                      ],
                    ),
                    decoration: BoxDecoration(
                      gradient: LinearGradient(
                        colors:  GradientColors.sunset,
                          begin: Alignment.centerLeft,
                        end: Alignment.centerRight
                      ),
                      borderRadius: BorderRadius.all(Radius.circular(24)),
                      boxShadow: [
                        BoxShadow(
                          color: GradientColors.sunset.last.withOpacity(0.4),
                            blurRadius: 5, spreadRadius: 2, offset: Offset(4,4)
                        )
                      ]
                    ),
                  );
                }).followedBy([
                  DottedBorder(
                    child: Container(
                    decoration: BoxDecoration(
                        color: Color(0xff3C3F69),
                          borderRadius: BorderRadius.all(Radius.circular(24))
                      ),
                    alignment: Alignment.center,
                      // color: Colors.red,
                      height: 110,
                      child: MaterialButton(
                        child: Column(
                          crossAxisAlignment: CrossAxisAlignment.stretch,
                          children: [
                            Icon(Icons.control_point, color: Colors.white,
                              size: 30,),
                            SizedBox(height: 8,),
                            Center(
                              child: Text('Add Alarm', style: TextStyle(
                                fontSize: 15, fontFamily: 'avenir',
                                  color: Colors.white,
                                  fontWeight: FontWeight.w700,
                              ),),
                            )
                          ],
                          mainAxisAlignment: MainAxisAlignment.center,
                        ),
                        onPressed: (){
                          Navigator.push(context, MaterialPageRoute(builder: (context){
                            return AddAlarmScreen();
                          }));
                        },
                      ),
                    ),
                    strokeWidth: 3,
                    color: Colors.white,
                    borderType: BorderType.RRect,
                    radius: Radius.circular(24),
                    dashPattern: [6, 6, 6],
                  ),
                ]).toList(),
                  );}
                  else{
                    return Center(
                      child: Text('Loading...', style: TextStyle(
                        color: Colors.white,
                        fontSize: 20
                      ),),
                    );
                  }
                
                }
              ),
            ),
          ),
        ],
      )
    );
  }
}

This is my code for the alarmHelper:

final String tableName = 'alarm';
final String id = 'id';
final String title = 'title';
final String dateTime = 'dateTime';
final String color = 'gradientColorIndex';
final String isPending = 'isPending';

class AlarmHelper{
  static Database? _database;
  static AlarmHelper? _alarmHelper;

  AlarmHelper._createInstance();
   factory AlarmHelper() {
    if (_alarmHelper == null){
      _alarmHelper = AlarmHelper._createInstance();
    }
    return _alarmHelper!;
  }

  Future<Database?> get database async{
    if (_database == null){
      _database = await initializeDatabase();
    }
    return _database!;
  }
  Future<Database> initializeDatabase() async{
    var dir = await getDatabasesPath();
    var path  = dir   "alarm.db";


    var database  = await openDatabase(path, version:  1, onCreate: (db, version){
      db.execute('''
      create table $tableName(
        $id integer primary key autoincrement,
        $title text not null,
        $dateTime text not null,
        $color integer,
        $isPending integer not null
      )
      ''');
    }
    );

    return database;
  }


  void insetAlarm(AlarmInfo alarmInfo) async{
     var db = await this.database;
     var result  = await db?.insert(tableName, alarmInfo.toMap());
     print(result);
  }


  Future<List<AlarmInfo>> getAlarm() async{
    var result;
    var db = await this.database;

      result = await db?.query(tableName);

     result.forEach((element) { 
      var alarmInfo  = AlarmInfo.fromMap(element);
      alarms.add(alarmInfo);
      }
      );

      return alarms;
  }

  void deleteAlarm(idOfAlarm) async{
     var db = await this.database;

     db?.delete(tableName, where: 'id = ?', whereArgs: [idOfAlarm]);
  }


}

The problem in more detail is that This is the screen currently with a single alarm on it.

enter image description here

But when I click off the screen and back on it, I will see the same element twice and this number increases by 1 every time I click off the screen and back on it, this is what it looks like.

enter image description here

CodePudding user response:

The code for AlarmHelper is incomplete, but looks with alarms.add(alarmInfo); you're adding new items to the alarms list, so each new call to getAlarms() returns a list with one more item.

  • Related