flutter 我想在点击时删除一个列表,但没有得到我所期望的

brtdzjyr  于 2023-08-07  发布在  Flutter
关注(0)|答案(1)|浏览(104)

我是Flutter的新手,目前正在开发一个学生记录应用程序。该应用程序使用列表平铺显示学生记录列表。然而,我在尝试实现删除功能时遇到了一个问题。我想让用户能够通过单击与学生数据关联的ListTile来删除学生记录。问题是,我当前的实现总是删除第一个索引ListTile,而不管单击的是哪一个。我使用的是SQFlite数据库。我在这里提供我的代码。
主镖

import 'package:flutter/material.dart';
import 'package:student/Screens/home_screen.dart';
import 'package:student/functions/functions.dart';

Future<void> main() async {
  WidgetsFlutterBinding.ensureInitialized();
  initializeDatabase();
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      debugShowCheckedModeBanner: false,
      theme: ThemeData.from(
        colorScheme: const ColorScheme.light(
      
            background: Colors.white,
            primary: Color.fromARGB(255, 0, 238, 226),
            brightness: Brightness.light,
            secondary: Color(0xff03dac6)),
      ),
      home: const HomeScreen(),
    );
  }
}

字符串
主页屏幕.dart

import 'dart:io';
import 'package:flutter/material.dart';
import 'package:student/Screens/add_student_screen.dart';
import 'package:student/Screens/edit_screen.dart';
import 'package:student/Screens/profile_student_screen.dart';

import 'package:student/functions/functions.dart';
import 'package:student/model/students.dart';

class HomeScreen extends StatefulWidget {
  const HomeScreen({super.key});

  @override
  State<HomeScreen> createState() => _HomeScreenState();
}

class _HomeScreenState extends State<HomeScreen> {
  bool isLoading = true;
  List<Students>? studentList;
  Students? student;

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

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('Student Record'),
        actions: [
          IconButton(
            onPressed: () {
              // Navigator.of(context).push(MaterialPageRoute(
              //   builder: (context) => const SearchScreen(),
              // ));
            },
            icon: const Icon(Icons.search),
          ),
          IconButton(
            onPressed: () {
              getAllStudents(student,context);
            },
            icon: const Icon(Icons.refresh),
          ),
        ],
      ),
      body: ValueListenableBuilder(
        builder: (BuildContext context, studentList, Widget? child) {
          return FutureBuilder(
              builder: (BuildContext context, AsyncSnapshot<dynamic> snapshot) {
            if (snapshot.hasError) {
              return const Center(
                child: Text('key'),
              );
            }
            return ListView.builder(
              itemCount: studentList.length,
              itemBuilder: (context, index) {
                final student = studentList[index];
                return SizedBox(
                  height: 60,
                  child: ListTile(
                    onTap: () {
                      Navigator.of(context).push(MaterialPageRoute(
                        builder: (context) => ProfileStudentScreen(
                          student: student,
                        ),
                      ));
                    },
                    leading: SizedBox.square(
                      dimension: 50,
                      child: ClipRRect(
                        borderRadius: BorderRadius.circular(50),
                        child: student.image.isEmpty
                            ? Image.network(
                                'https://cdn.pixabay.com/photo/2015/10/05/22/37/blank-profile-picture-973460_1280.png')
                            : Image.file(
                                File(student.image),
                                fit: BoxFit.cover,
                              ),
                      ),
                    ),
                    title: Text(student.name),
                    trailing: Wrap(
                      spacing: 20,
                      direction: Axis.horizontal,
                      children: [
                        IconButton(
                          onPressed: () {
                            Navigator.of(context).push(
                              MaterialPageRoute(
                                  builder: (context) => EditStudentScreen(
                                        student: student,
                                      )),
                            );
                          },
                          icon: const Icon(Icons.edit),
                        ),
                        IconButton(
                          onPressed: () {
                            deleteStudent(studentList[index].id! , context);
                          },
                          icon: const Icon(Icons.delete),
                        ),
                      ],
                    ),
                  ),
                );
              },
            );
          });
        },
        valueListenable: studentListNotifier,
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: () async {
          await Navigator.push(
            context,
            MaterialPageRoute(
              builder: (context) => AddStudentScreen(),
            ),
          );
        },
        child: const Icon(Icons.add),
      ),
    );
  }
}


studentsModel.dart

const String studentsTable = 'students';

class StudentsFields {
  static final List<String> values = [id, name, age, email, domain, image];
  static const String id = 'id';
  static const String name = 'name';
  static const String age = 'age';
  static const String email = 'email';
  static const String domain = 'domain';
  static const String image = 'image';
}

class Students {
  int? id;
  String name;
  int? age;
  String email;
  String domain;
  String image;

  Students({
    this.id,
    this.name = '',
    this.age = 0,
    this.email = '',
    this.domain = '',
    this.image = '',
  });

  Students copy({
    int? id,
    String? name,
    int? age,
    String? email,
    String? domain,
    String? image,
  }) =>
      Students(
        id: id ?? this.id,
        name: name ?? this.name,
        age: age ?? this.age,
        email: email ?? this.email,
        domain: domain ?? this.domain,
        image: image ?? this.image,
      );

  static Students fromMap(Map<String, Object?> map) {
    final id = map['id'] as int;
    final name = map['name'] as String;
    final age = map['age'] as int;
    final email = map['email'] as String;
    final domain = map['domain'] as String;
    final image = map['image'] as String;

    return Students(
      id: id,
      name: name,
      age: age,
      email: email,
      domain: domain,
      image: image,
    );
  }

  Map<String, dynamic> toMap() {
    return {
      StudentsFields.id: id,
      StudentsFields.name: name,
      StudentsFields.age: age,
      StudentsFields.email: email,
      StudentsFields.domain: domain,
      StudentsFields.image: image,
    };
  }
}


数据库功能

// ignore_for_file: invalid_use_of_protected_member, invalid_use_of_visible_for_testing_member

import 'dart:developer';

import 'package:flutter/material.dart';
import 'package:sqflite/sqflite.dart';

import 'package:student/model/students.dart';

ValueNotifier<List<Students>> studentListNotifier = ValueNotifier([]);
late Database _db;

Future<void> initializeDatabase() async {
  _db = await openDatabase('student.db', version: 1, onCreate: (db, version) {
    db.execute('''
      CREATE TABLE $studentsTable (
        ${StudentsFields.id} INTEGER PRIMARY KEY  NOT NULL,
        ${StudentsFields.name} TEXT,
        ${StudentsFields.age} INTEGER NOT NULL,
        ${StudentsFields.email} TEXT,
        ${StudentsFields.domain} TEXT,
        ${StudentsFields.image} TEXT
      )
    ''');
  });
}

Future<void> getAllStudents(Students? student, BuildContext ctx) async {
  studentListNotifier.value.clear();
  try {
    final values = await _db.rawQuery('SELECT * FROM $studentsTable');
    for (var map in values) {
      final student = Students.fromMap(map);
      studentListNotifier.value.add(student);
      studentListNotifier.notifyListeners();
      log("SUcess");
    }
  } catch (e) {
    log("Error getting data : $e");
    showDialog(
      context: ctx,
      builder: (context) => const AlertDialog(
        title: Text("Warning"),
      ),
    );
  }
}

Future<void> addStudent(Students student, BuildContext ctx) async {
  try {
    await _db.rawInsert(
      'INSERT INTO $studentsTable (${StudentsFields.name},${StudentsFields.age},${StudentsFields.email},${StudentsFields.domain},${StudentsFields.image}) VALUES (?, ?, ?, ?, ?)',
      [student.name, student.age, student.email, student.domain, student.image],
    );
    studentListNotifier.value.add(student);

    studentListNotifier.notifyListeners();
  } catch (e) {
    log('Error updating student: $e');
    showDialog(
      context: ctx,
      builder: (context) => const AlertDialog(
        title: Text("Warning"),
      ),
    );
  }
}

Future<void> editStudent(Students student, BuildContext ctx) async {
  try {
    final updatedRows = await _db.rawUpdate(
      'UPDATE $studentsTable SET '
      'WHERE ${StudentsFields.age} = ?, '
      '${StudentsFields.email} = ?, '
      '${StudentsFields.domain} = ? '
      ' ${StudentsFields.name} = ?',
      [
        student.age,
        student.email,
        student.domain,
        student.name,
      ],
    );
    ScaffoldMessenger.of(ctx).showSnackBar(const SnackBar(
      backgroundColor: Colors.green,
      content: Text("Sucesfully Updated"),
      duration: Duration(milliseconds: 600),
    ));
    if (updatedRows > 0) {
      studentListNotifier.notifyListeners();
      log('Success: Student updated');
    } else {
      log('No rows updated.');
    }
  } catch (e) {
    log('Error updating student: $e');
    ScaffoldMessenger.of(ctx).showSnackBar(const SnackBar(
      backgroundColor: Colors.red,
      content: Text("Error occured"),
      duration: Duration(milliseconds: 600),
    ));
  }
}

Future<void> deleteStudent(int id, BuildContext ctx) async {
  try {
    await _db.rawDelete(
      'DELETE FROM $studentsTable WHERE $id = ?',
      [id],
    );

    studentListNotifier.value.removeAt(id);
    studentListNotifier.notifyListeners();
    log('Success: Student deleted');
  } catch (e) {
    log('Error deleting student: $e');
    showDialog(
      context: ctx,
      builder: (context) => const AlertDialog(
        title: Text("Warning"),
      ),
    );
  }
}

Future<void> refreshList(BuildContext ctx) async {
  try {
    final values = await _db.rawQuery('SELECT * FROM $studentsTable');

    studentListNotifier.value =
        values.map((map) => Students.fromMap(map)).toList();
    studentListNotifier.notifyListeners();
  } catch (e) {
    log("Error refreshing data");
    showDialog(
      context: ctx,
      builder: (context) => const AlertDialog(
        title: Text("Warning"),
      ),
    );
  }
}


我也提供了我的搜索屏幕与它。请更正它我想通过搜索名称显示数据。

import 'dart:io';
import 'package:flutter/material.dart';
import 'package:student/model/students.dart';
import 'package:student/Screens/profile_student_screen.dart';

class SearchScreen extends StatefulWidget {
  final List<Students>? studentList;

  const SearchScreen({required this.studentList, Key? key}) : super(key: key);

  @override
  State<SearchScreen> createState() => _SearchScreenState();
}

class _SearchScreenState extends State<SearchScreen> {
  List<Students> filteredList = [];
  String searchQuery = '';

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('Search Students'),
      ),
      body: Column(
        children: [
          Padding(
            padding: const EdgeInsets.all(16.0),
            child: TextField(
              onChanged: (value) {
                setState(() {
                  searchQuery = value;
                  filteredList = widget.studentList!
                      .where((student) => student.name
                          .toLowerCase()
                          .contains(value.toLowerCase()))
                      .toList();
                });
              },
              decoration: const InputDecoration(
                hintText: 'Search by name...',
                prefixIcon: Icon(Icons.search),
              ),
            ),
          ),
          Expanded(
            child: _buildStudentList(),
          ),
        ],
      ),
    );
  }

  Widget _buildStudentList() {
    if (filteredList.isEmpty) {
      return const Center(child: Text('No students found'));
    } else {
      return ListView.builder(
        itemCount: filteredList.length,
        itemBuilder: (context, index) {
          final student = filteredList[index];
          return ListTile(
            leading: SizedBox.square(
              dimension: 50,
              child: ClipRRect(
                borderRadius: BorderRadius.circular(50),
                child: student.image.isEmpty
                    ? Image.network(
                        'https://cdn.pixabay.com/photo/2015/10/05/22/37/blank-profile-picture-973460_1280.png')
                    : Image.file(
                        File(student.image),
                        fit: BoxFit.cover,
                      ),
              ),
            ),
            title: Text(student.name),
            onTap: () {
              // Handle tapping on the student in the search results.
              Navigator.of(context).push(
                MaterialPageRoute(
                  builder: (context) => ProfileStudentScreen(student: student),
                ),
              );
            },
          );
        },
      );
    }
  }
}

  • 更新 *:
import 'dart:io';
import 'package:flutter/material.dart';
import 'package:student/Screens/add_student_screen.dart';
import 'package:student/Screens/edit_screen.dart';
import 'package:student/Screens/profile_student_screen.dart';

import 'package:student/functions/functions.dart';
import 'package:student/model/students.dart';

class HomeScreen extends StatefulWidget {
  const HomeScreen({super.key});

  @override
  State<HomeScreen> createState() => _HomeScreenState();
}

class _HomeScreenState extends State<HomeScreen> {
  bool isLoading = true;
  List<Students>? studentList;
  Students? student;

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

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('Student Record'),
        actions: [
          IconButton(
            onPressed: () {
              // Navigator.of(context).push(MaterialPageRoute(
              //   builder: (context) => const SearchScreen(),
              // ));
            },
            icon: const Icon(Icons.search),
          ),
         
        ],
      ),
      body: ValueListenableBuilder(
        builder: (BuildContext context, studentList, Widget? child) {
          return ListView.builder(
              itemCount: studentList.length,
              itemBuilder: (context, index) {
                final student = studentList[index];
                return SizedBox(
                  height: 60,
                  child: ListTile(
                    onTap: () {
                      Navigator.of(context).push(MaterialPageRoute(
                        builder: (context) => ProfileStudentScreen(
                          student: student,
                        ),
                      ));
                    },
                    leading: SizedBox.square(
                      dimension: 50,
                      child: ClipRRect(
                        borderRadius: BorderRadius.circular(50),
                        child: student.image.isEmpty
                            ? Image.network(
                                'https://cdn.pixabay.com/photo/2015/10/05/22/37/blank-profile-picture-973460_1280.png')
                            : Image.file(
                                File(student.image),
                                fit: BoxFit.cover,
                              ),
                      ),
                    ),
                    title: Text(student.name),
                    trailing: Wrap(
                      spacing: 20,
                      direction: Axis.horizontal,
                      children: [
                        IconButton(
                          onPressed: () {
                            Navigator.of(context).push(
                              MaterialPageRoute(
                                  builder: (context) => EditStudentScreen(
                                        student: student,
                                      )),
                            );
                          },
                          icon: const Icon(Icons.edit),
                        ),
                        IconButton(
                          onPressed: () {
                            deleteStudent(studentList[index].id!);
                          },
                          icon: const Icon(Icons.delete),
                        ),
                      ],
                    ),
                  ),
                );
              },
            );
          
        },
        valueListenable: studentListNotifier,
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: () async {
          await Navigator.push(
            context,
            MaterialPageRoute(
              builder: (context) => AddStudentScreen(),
            ),
          );
        },
        child: const Icon(Icons.add),
      ),
    );
  }
}

更改未来版本已删除。

添加学生屏幕:

import 'package:flutter/material.dart';
import 'package:image_picker/image_picker.dart';
import 'package:student/functions/functions.dart';
import 'package:student/model/students.dart';

class AddStudentScreen extends StatefulWidget {
  final Students? student;

  const AddStudentScreen({
    super.key,
    this.student,
  });

  @override
  State<AddStudentScreen> createState() => _AddEditStudentScreenState();
}

class _AddEditStudentScreenState extends State<AddStudentScreen> {
  final _formKey = GlobalKey<FormState>();
  final _nameController = TextEditingController();
  final _ageController = TextEditingController();
  final _emailController = TextEditingController();
  final _domainController = TextEditingController();
  final _imageController = TextEditingController();

/*Image Picker Functions    */
  XFile? _imageFile;

  Future<void> _getImageFromCamera() async {
    final pickedFile =
        await ImagePicker().pickImage(source: ImageSource.camera);
    if (pickedFile != null) {
      setState(() {
        _imageFile = XFile(pickedFile.path);
      });
    }
  }

  Future<void> _getImageFromGallery() async {
    final pickedFile =
        await ImagePicker().pickImage(source: ImageSource.gallery);
    if (pickedFile != null) {
      setState(() {
        _imageFile = XFile(pickedFile.path);
      });
    }
  }

  @override
  void dispose() {
    _nameController.dispose();
    _ageController.dispose();
    _emailController.dispose();
    _domainController.dispose();
    _imageController.dispose();
    super.dispose();
  }
// Image picker end here

//Email validation
  bool isEmailValid(String email) {
    final emailRegExp = RegExp(
        r"^[a-zA-Z0-9.a-zA-Z0-9.!#$%&'*+-/=?^_`{|}~]+@[a-zA-Z0-9]+\.[a-zA-Z]+");

    return emailRegExp.hasMatch(email);
  }

  // Save Student Function

  void _saveStudent() async {
    if (_formKey.currentState!.validate()) {
      final newStudent = Students(
        id: int.tryParse(StudentsFields.id) ?? 0,
        name: _nameController.text,
        age: int.tryParse(_ageController.text) ?? 0,
        email: _emailController.text,
        domain: _domainController.text,
        image: _imageFile?.path ?? '',
      );

      addStudents(newStudent);
      Navigator.of(context).pop();
    }
  }

  @override
  Widget build(BuildContext context) {
    final size = MediaQuery.of(context).size;
    return Scaffold(
      appBar: AppBar(
        title: const Text(
          "Add Student",
        ),
      ),
      body: Padding(
        padding: const EdgeInsets.all(16.0),
        child: Form(
          key: _formKey,
          child: SingleChildScrollView(
            child: Column(
              crossAxisAlignment: CrossAxisAlignment.start,
              children: [
                TextFormField(
                  controller: _nameController,
                  decoration: const InputDecoration(labelText: 'Name'),
                  validator: (value) {
                    if (value == null || value.isEmpty) {
                      return 'Please enter a name';
                    }
                    return null;
                  },
                ),
                TextFormField(
                  controller: _ageController,
                  keyboardType: TextInputType.number,
                  decoration: const InputDecoration(
                    labelText: 'Age',
                  ),
                  validator: (value) {
                    if (value == null || value.isEmpty) {
                      return 'Please enter an age';
                    }
                    return null;
                  },
                ),
                TextFormField(
                  controller: _emailController,
                  keyboardType: TextInputType.emailAddress,
                  decoration: const InputDecoration(labelText: 'Email'),
                  validator: (value) {
                    if (value == null || value.isEmpty) {
                      return 'Please enter your email';
                    } else if (!isEmailValid(value)) {
                      return 'Invalid email';
                    }
                    return null;
                  },
                ),
                TextFormField(
                  controller: _domainController,
                  decoration: const InputDecoration(
                      labelText: 'Domain',
                      labelStyle: TextStyle(color: Colors.black)),
                  validator: (value) {
                    if (value == null || value.isEmpty) {
                      return 'Please enter your domain';
                    }
                    return null;
                  },
                ),
                const SizedBox(
                  height: 20,
                ),
                Padding(
                  padding: const EdgeInsets.all(8.0),
                  child: Row(
                    mainAxisAlignment: MainAxisAlignment.spaceEvenly,
                    children: [
                      ElevatedButton.icon(
                        style: ElevatedButton.styleFrom(
                            backgroundColor: Colors.black),
                        onPressed: _getImageFromCamera,
                        icon: const Icon(
                          Icons.camera,
                          color: Colors.white,
                        ),
                        label: const Text(
                          'Camera',
                          style: TextStyle(color: Colors.white),
                        ),
                      ),
                      ElevatedButton.icon(
                        style: ElevatedButton.styleFrom(
                            backgroundColor: Colors.black),
                        onPressed: _getImageFromGallery,
                        icon: const Icon(
                          Icons.upload,
                          color: Colors.white,
                        ),
                        label: const Text(
                          'Upload',
                          style: TextStyle(color: Colors.white),
                        ),
                      ),
                    ],
                  ),
                ),
                SizedBox(
                  width: size.width,
                  child: ElevatedButton(
                    style:
                        ElevatedButton.styleFrom(backgroundColor: Colors.black),
                    onPressed: () async {
                      _saveStudent();
                    },
                    child: const Text(
                      'Save',
                      style: TextStyle(
                        color: Colors.white,
                        fontWeight: FontWeight.bold,
                        fontSize: 20,
                      ),
                    ),
                  ),
                ),
              ],
            ),
          ),
        ),
      ),
    );
  }
}


我进入了一个错误,在addstudent页面输入的数据没有显示在主界面

pb3skfrl

pb3skfrl1#

IconButton(
  onPressed: () {
    deleteStudent(studentList[index].id! , context);
      },
    icon: const Icon(Icons.delete),

字符串
代替这种用途,

IconButton(
  onPressed: () {
   deleteStudent(student.id , context);
     },
   icon: const Icon(Icons.delete),

相关问题