Last active
February 11, 2025 11:24
-
-
Save Lusmaysh/76b64fc7281cb60c19d1ca7ddec6eef9 to your computer and use it in GitHub Desktop.
mod for main.dart, list and grid class are separated
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import 'package:flutter/material.dart'; | |
import 'package:shared_preferences/shared_preferences.dart'; | |
void main() { | |
runApp(MyApp()); | |
} | |
class MyApp extends StatelessWidget { | |
@override | |
Widget build(BuildContext context) { | |
return MaterialApp( | |
title: 'CRUD ListView Dan GridView', | |
theme: ThemeData( | |
primarySwatch: Colors.blue, | |
), | |
home: MainPage(), | |
debugShowCheckedModeBanner: false, | |
); | |
} | |
} | |
// bagian ListView dan GridView | |
class MainPage extends StatefulWidget { | |
@override | |
_MainPageState createState() => _MainPageState(); | |
} | |
class _MainPageState extends State<MainPage> { | |
List<String> kodePT = []; | |
List<String> namaPT = []; | |
List<String> alamatPT = []; | |
bool isGridView = false; | |
@override | |
void initState() { | |
super.initState(); | |
_loadData(); | |
} | |
_loadData() async { | |
SharedPreferences prefs = await SharedPreferences.getInstance(); | |
setState(() { | |
kodePT = prefs.getStringList('kodePT') ?? []; | |
namaPT = prefs.getStringList('namaPT') ?? []; | |
alamatPT = prefs.getStringList('alamatPT') ?? []; | |
}); | |
} | |
_deleteData(int index) async { | |
bool confirmDelete = await _showDeleteConfirmationDialog(); | |
if (confirmDelete) { | |
SharedPreferences prefs = await SharedPreferences.getInstance(); | |
setState(() { | |
kodePT.removeAt(index); | |
namaPT.removeAt(index); | |
alamatPT.removeAt(index); | |
}); | |
await prefs.setStringList('kodePT', kodePT); | |
await prefs.setStringList('namaPT', namaPT); | |
await prefs.setStringList('alamatPT', alamatPT); | |
} | |
} | |
Future<bool> _showDeleteConfirmationDialog() async { | |
return await showDialog( | |
context: context, | |
builder: (BuildContext context) { | |
return AlertDialog( | |
title: Text('Konfirmasi Hapus'), | |
content: Text('Apakah Anda yakin ingin menghapus data ini?'), | |
actions: [ | |
TextButton( | |
child: Text('Batal'), | |
onPressed: () { | |
Navigator.of(context).pop(false); | |
}, | |
), | |
TextButton( | |
child: Text('Hapus'), | |
onPressed: () { | |
Navigator.of(context).pop(true); | |
}, | |
), | |
], | |
); | |
}, | |
); | |
} | |
@override | |
Widget build(BuildContext context) { | |
return Scaffold( | |
appBar: AppBar( | |
title: Text('Data Perguruan Tinggi'), | |
backgroundColor: Colors.blueAccent, | |
actions: [ | |
IconButton( | |
icon: Icon(isGridView ? Icons.list : Icons.grid_view), | |
onPressed: () { | |
setState(() { | |
isGridView = !isGridView; | |
}); | |
}, | |
) | |
], | |
), | |
body: kodePT.isEmpty | |
? Center( | |
child: Text( | |
'Belum ada data. Silakan tambahkan data baru.', | |
style: TextStyle(fontSize: 18), | |
), | |
) | |
: isGridView | |
? GridViewPage(kodePT: kodePT, namaPT: namaPT, alamatPT: alamatPT) | |
: ListViewPage( | |
kodePT: kodePT, | |
namaPT: namaPT, | |
alamatPT: alamatPT, | |
onEdit: (index) async { | |
final updated = await Navigator.push( | |
context, | |
MaterialPageRoute( | |
builder: (context) => FormPage( | |
index: index, | |
kodePT: kodePT[index], | |
namaPT: namaPT[index], | |
alamatPT: alamatPT[index], | |
), | |
), | |
); | |
if (updated != null) _loadData(); | |
}, | |
onDelete: _deleteData, | |
), | |
floatingActionButton: FloatingActionButton( | |
child: Icon(Icons.add), | |
onPressed: () async { | |
final added = await Navigator.push( | |
context, | |
MaterialPageRoute( | |
builder: (context) => FormPage(), | |
), | |
); | |
if (added != null) _loadData(); | |
}, | |
), | |
); | |
} | |
} | |
class GridViewPage extends StatelessWidget { | |
final List<String> kodePT; | |
final List<String> namaPT; | |
final List<String> alamatPT; | |
GridViewPage({ | |
required this.kodePT, | |
required this.namaPT, | |
required this.alamatPT, | |
}); | |
@override | |
Widget build(BuildContext context) { | |
return GridView.builder( | |
padding: EdgeInsets.all(8), | |
itemCount: kodePT.length, | |
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount( | |
crossAxisCount: 2, | |
crossAxisSpacing: 10, | |
mainAxisSpacing: 10, | |
), | |
itemBuilder: (context, index) { | |
return Card( | |
elevation: 4, | |
child: InkWell( | |
onTap: () {}, | |
child: Column( | |
mainAxisAlignment: MainAxisAlignment.center, | |
children: [ | |
CircleAvatar( | |
child: Text(kodePT[index][0].toUpperCase()), | |
), | |
SizedBox(height: 10), | |
Text(namaPT[index], | |
style: | |
TextStyle(fontWeight: FontWeight.bold, fontSize: 16)), | |
Text(alamatPT[index]), | |
], | |
), | |
), | |
); | |
}, | |
); | |
} | |
} | |
class ListViewPage extends StatelessWidget { | |
final List<String> kodePT; | |
final List<String> namaPT; | |
final List<String> alamatPT; | |
final Function(int) onEdit; | |
final Function(int) onDelete; | |
ListViewPage({ | |
required this.kodePT, | |
required this.namaPT, | |
required this.alamatPT, | |
required this.onEdit, | |
required this.onDelete, | |
}); | |
@override | |
Widget build(BuildContext context) { | |
return ListView.builder( | |
padding: EdgeInsets.all(8), | |
itemCount: kodePT.length, | |
itemBuilder: (context, index) { | |
return Card( | |
elevation: 4, | |
margin: EdgeInsets.symmetric(vertical: 8), | |
child: InkWell( | |
onTap: () {}, | |
child: ListTile( | |
leading: CircleAvatar( | |
child: Text(kodePT[index][0].toUpperCase()), | |
), | |
title: Text(namaPT[index]), | |
subtitle: Text(alamatPT[index]), | |
trailing: Row( | |
mainAxisSize: MainAxisSize.min, | |
children: [ | |
IconButton( | |
icon: Icon(Icons.edit, color: Colors.green), | |
onPressed: () => onEdit(index), | |
), | |
IconButton( | |
icon: Icon(Icons.delete, color: Colors.red), | |
onPressed: () => onDelete(index), | |
), | |
], | |
), | |
), | |
), | |
); | |
}, | |
); | |
} | |
} | |
// Halaman input dan edit digabung | |
class FormPage extends StatefulWidget { | |
final int? index; | |
final String? kodePT; | |
final String? namaPT; | |
final String? alamatPT; | |
FormPage({this.index, this.kodePT, this.namaPT, this.alamatPT}); | |
@override | |
_FormPageState createState() => _FormPageState(); | |
} | |
class _FormPageState extends State<FormPage> { | |
final _formKey = GlobalKey<FormState>(); | |
late TextEditingController _kodePTController; | |
late TextEditingController _namaPTController; | |
late TextEditingController _alamatPTController; | |
@override | |
void initState() { | |
super.initState(); | |
_kodePTController = TextEditingController(text: widget.kodePT ?? ''); | |
_namaPTController = TextEditingController(text: widget.namaPT ?? ''); | |
_alamatPTController = TextEditingController(text: widget.alamatPT ?? ''); | |
} | |
_saveOrUpdateData() async { | |
if (_formKey.currentState!.validate()) { | |
SharedPreferences prefs = await SharedPreferences.getInstance(); | |
List<String> kodePT = prefs.getStringList('kodePT') ?? []; | |
List<String> namaPT = prefs.getStringList('namaPT') ?? []; | |
List<String> alamatPT = prefs.getStringList('alamatPT') ?? []; | |
if (widget.index == null) { | |
// Add new data | |
kodePT.add(_kodePTController.text); | |
namaPT.add(_namaPTController.text); | |
alamatPT.add(_alamatPTController.text); | |
} else { | |
// Update existing data | |
kodePT[widget.index!] = _kodePTController.text; | |
namaPT[widget.index!] = _namaPTController.text; | |
alamatPT[widget.index!] = _alamatPTController.text; | |
} | |
await prefs.setStringList('kodePT', kodePT); | |
await prefs.setStringList('namaPT', namaPT); | |
await prefs.setStringList('alamatPT', alamatPT); | |
Navigator.pop(context, true); // Berhasil disimpan atau diupdate | |
} | |
} | |
@override | |
Widget build(BuildContext context) { | |
return Scaffold( | |
appBar: AppBar( | |
title: Text(widget.index == null | |
? 'Tambah Data Perguruan Tinggi' | |
: 'Edit Data Perguruan Tinggi'), | |
backgroundColor: | |
widget.index == null ? Colors.blueAccent : Colors.green, | |
), | |
body: Padding( | |
padding: const EdgeInsets.all(16.0), | |
child: Form( | |
key: _formKey, | |
child: Column( | |
children: [ | |
TextFormField( | |
controller: _kodePTController, | |
decoration: InputDecoration( | |
labelText: 'Kode Perguruan Tinggi', | |
border: OutlineInputBorder(), | |
), | |
validator: (value) => | |
value!.isEmpty ? 'Kode tidak boleh kosong' : null, | |
), | |
SizedBox(height: 16), | |
TextFormField( | |
controller: _namaPTController, | |
decoration: InputDecoration( | |
labelText: 'Nama Perguruan Tinggi', | |
border: OutlineInputBorder(), | |
), | |
validator: (value) => | |
value!.isEmpty ? 'Nama tidak boleh kosong' : null, | |
), | |
SizedBox(height: 16), | |
TextFormField( | |
controller: _alamatPTController, | |
decoration: InputDecoration( | |
labelText: 'Alamat Perguruan Tinggi', | |
border: OutlineInputBorder(), | |
), | |
validator: (value) => | |
value!.isEmpty ? 'Alamat tidak boleh kosong' : null, | |
), | |
SizedBox(height: 16), | |
ElevatedButton( | |
onPressed: _saveOrUpdateData, | |
child: Text(widget.index == null ? 'Simpan' : 'Update'), | |
), | |
], | |
), | |
), | |
), | |
); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment