Skip to content

Instantly share code, notes, and snippets.

@Lusmaysh
Last active February 11, 2025 11:24
Show Gist options
  • Save Lusmaysh/76b64fc7281cb60c19d1ca7ddec6eef9 to your computer and use it in GitHub Desktop.
Save Lusmaysh/76b64fc7281cb60c19d1ca7ddec6eef9 to your computer and use it in GitHub Desktop.
mod for main.dart, list and grid class are separated
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