implemented IconPicker for Car class
This commit is contained in:
@@ -9,6 +9,7 @@ import 'package:dash/screens/screens.dart';
|
||||
class CarDetailScreen extends StatefulWidget {
|
||||
const CarDetailScreen({super.key, required this.carIndex});
|
||||
final int carIndex;
|
||||
// late Car car;
|
||||
|
||||
@override
|
||||
State<CarDetailScreen> createState() => _CarDetailScreenState();
|
||||
@@ -20,13 +21,13 @@ class _CarDetailScreenState extends State<CarDetailScreen> {
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
// late Car car = Provider.of<GarageModel>(context).cars[widget.carIndex];
|
||||
late Car car = Provider.of<GarageModel>(context).cars[widget.carIndex];
|
||||
// late Car car = context.watch<GarageModel>()_cars[widget.carIndex];
|
||||
return Scaffold(
|
||||
appBar: AppBar(
|
||||
backgroundColor: const Color.fromARGB(255, 185, 47, 5),
|
||||
// title: Text(car.nickname ?? ""),
|
||||
title: const Text("View Car"),
|
||||
title: Text(car.nickname ?? ""),
|
||||
// title: const Text("View Car"),
|
||||
),
|
||||
body: Padding(
|
||||
padding: const EdgeInsets.all(16.0),
|
||||
@@ -36,7 +37,6 @@ class _CarDetailScreenState extends State<CarDetailScreen> {
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
|
||||
children: [
|
||||
const Text("plh img picker"),
|
||||
Center(
|
||||
// edit car screen
|
||||
child: Ink(
|
||||
@@ -58,11 +58,6 @@ class _CarDetailScreenState extends State<CarDetailScreen> {
|
||||
),
|
||||
],
|
||||
),
|
||||
IconButton(
|
||||
iconSize: 48.0,
|
||||
icon: const Icon(Icons.directions_car),
|
||||
onPressed: (() => VoidCallback),
|
||||
),
|
||||
Consumer<GarageModel>(
|
||||
builder: (context, garage, child) => Column(
|
||||
children: [
|
||||
@@ -71,6 +66,11 @@ class _CarDetailScreenState extends State<CarDetailScreen> {
|
||||
Text("License Plate: ${garage.cars[widget.carIndex].plate}"),
|
||||
Text(
|
||||
"Mileage: ${garage.cars[widget.carIndex].mileage.toString()}"),
|
||||
CircleAvatar(
|
||||
backgroundImage: AssetImage(
|
||||
garage.cars[widget.carIndex].icon ??
|
||||
'images/car.png'),
|
||||
backgroundColor: Colors.white),
|
||||
],
|
||||
),
|
||||
),
|
||||
@@ -97,10 +97,10 @@ class CarTxns extends StatefulWidget {
|
||||
final int carIndex;
|
||||
|
||||
@override
|
||||
State<CarTxns> createState() => _CurrentCar();
|
||||
State<CarTxns> createState() => _CarTxns();
|
||||
}
|
||||
|
||||
class _CurrentCar extends State<CarTxns> {
|
||||
class _CarTxns extends State<CarTxns> {
|
||||
late Future _txns;
|
||||
late Car car;
|
||||
|
||||
@@ -112,10 +112,22 @@ class _CurrentCar extends State<CarTxns> {
|
||||
super.initState();
|
||||
}
|
||||
|
||||
Icon getIcon(String? txntype) {
|
||||
if (txntype == 'Gas') {
|
||||
return (const Icon(Icons.local_gas_station));
|
||||
} else if (txntype == 'Oil') {
|
||||
return (const Icon(Icons.water_drop));
|
||||
} else if (txntype == 'Other') {
|
||||
return (const Icon(Icons.build));
|
||||
} else {
|
||||
return (const Icon(Icons.question_mark));
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
// car =
|
||||
// Provider.of<GarageModel>(context, listen: false).cars[widget.carIndex];
|
||||
// Provider.of<GarageModel>(context, listen: false).cars[widget.carIndex];
|
||||
// _txns = Provider.of<GarageModel>(context, listen: false).getTxns(car.id!);
|
||||
return FutureBuilder(
|
||||
future: _txns,
|
||||
@@ -139,7 +151,7 @@ class _CurrentCar extends State<CarTxns> {
|
||||
// dense: true, //only affects text, use visualDensity instead
|
||||
visualDensity:
|
||||
const VisualDensity(horizontal: 0, vertical: -4),
|
||||
leading: const Icon(Icons.local_gas_station),
|
||||
leading: getIcon(garage.txns[index].txntype),
|
||||
title: Text(garage.txns[index].txntype ?? "type"),
|
||||
subtitle: Text(garage.txns[index].note ?? "note"),
|
||||
onTap: (() => VoidCallback)),
|
||||
|
||||
@@ -2,6 +2,7 @@ import 'package:flutter/material.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
import 'package:dash/utils/garage_model.dart';
|
||||
import 'package:dash/models/car.dart';
|
||||
import 'package:dash/screens/iconpicker.dart';
|
||||
|
||||
class EditCarScreen extends StatefulWidget {
|
||||
const EditCarScreen({super.key, required this.carIndex});
|
||||
@@ -16,6 +17,8 @@ class _EditCarScreenState extends State<EditCarScreen> {
|
||||
late GarageModel garage;
|
||||
late Car car;
|
||||
late int carIndex = widget.carIndex;
|
||||
late IconPicker ip = IconPicker();
|
||||
late String selectedIcon = 'images/car.png';
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
@@ -98,6 +101,22 @@ class _EditCarScreenState extends State<EditCarScreen> {
|
||||
return null;
|
||||
},
|
||||
),
|
||||
ListTile(
|
||||
leading: CircleAvatar(
|
||||
backgroundImage: AssetImage(car.icon ?? selectedIcon),
|
||||
backgroundColor: Colors.white),
|
||||
title: const Text("Change Icon"),
|
||||
onTap: () => showDialog(
|
||||
barrierColor: Colors.black.withOpacity(.5),
|
||||
context: context,
|
||||
builder: (BuildContext context) {
|
||||
return ip;
|
||||
}).then((value) => setState(
|
||||
() {
|
||||
// selectedIcon = ip.selectedIcon;
|
||||
selectedIcon = value;
|
||||
},
|
||||
))),
|
||||
Padding(
|
||||
padding: const EdgeInsets.symmetric(vertical: 4.0),
|
||||
child: ElevatedButton(
|
||||
@@ -107,6 +126,7 @@ class _EditCarScreenState extends State<EditCarScreen> {
|
||||
//validate form
|
||||
updateForm
|
||||
.save(); //save values (reqd before putting them anywhere)
|
||||
car.icon = selectedIcon;
|
||||
garage.update(car, carIndex);
|
||||
updateForm.reset();
|
||||
Navigator.pop(context);
|
||||
|
||||
@@ -2,7 +2,7 @@ import 'package:flutter/material.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
import 'package:dash/utils/garage_model.dart';
|
||||
import 'package:dash/models/car.dart';
|
||||
import '../utils/garage_model.dart';
|
||||
import 'package:dash/screens/screens.dart';
|
||||
|
||||
class NewCarScreen extends StatefulWidget {
|
||||
const NewCarScreen({super.key});
|
||||
@@ -14,6 +14,8 @@ class NewCarScreen extends StatefulWidget {
|
||||
class _NewCarScreenState extends State<NewCarScreen> {
|
||||
final GlobalKey<FormState> formKey = GlobalKey<FormState>();
|
||||
Car car = Car(); //initialization is required
|
||||
late IconPicker ip = IconPicker();
|
||||
late String selectedIcon = 'images/car.png';
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
@@ -29,7 +31,6 @@ class _NewCarScreenState extends State<NewCarScreen> {
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: <Widget>[
|
||||
//new car form text fields
|
||||
TextFormField(
|
||||
decoration: const InputDecoration(
|
||||
labelText: 'Nickname',
|
||||
@@ -81,6 +82,22 @@ class _NewCarScreenState extends State<NewCarScreen> {
|
||||
return null;
|
||||
},
|
||||
),
|
||||
ListTile(
|
||||
leading: CircleAvatar(
|
||||
backgroundImage: AssetImage(selectedIcon),
|
||||
backgroundColor: Colors.white),
|
||||
title: const Text("Change Icon"),
|
||||
onTap: () => showDialog(
|
||||
barrierColor: Colors.black.withOpacity(.5),
|
||||
context: context,
|
||||
builder: (BuildContext context) {
|
||||
return ip;
|
||||
}).then((value) => setState(
|
||||
() {
|
||||
// selectedIcon = ip.selectedIcon;
|
||||
selectedIcon = value;
|
||||
},
|
||||
))),
|
||||
Padding(
|
||||
padding: const EdgeInsets.symmetric(vertical: 16.0),
|
||||
child: ElevatedButton(
|
||||
@@ -96,6 +113,7 @@ class _NewCarScreenState extends State<NewCarScreen> {
|
||||
vin: car.vin,
|
||||
nickname: car.nickname,
|
||||
plate: car.plate,
|
||||
icon: selectedIcon,
|
||||
mileage: car.mileage);
|
||||
});
|
||||
// var garage = context.read<GarageModel>();
|
||||
|
||||
97
lib/screens/iconpicker.dart
Normal file
97
lib/screens/iconpicker.dart
Normal file
@@ -0,0 +1,97 @@
|
||||
import 'dart:convert';
|
||||
import 'dart:async';
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
class IconPicker extends StatefulWidget {
|
||||
IconPicker({super.key});
|
||||
|
||||
late String selectedIcon = 'images/car.png';
|
||||
|
||||
@override
|
||||
State<IconPicker> createState() => _IconPickerState();
|
||||
}
|
||||
|
||||
class _IconPickerState extends State<IconPicker> {
|
||||
late Future<String> manifestJson;
|
||||
late List<String> icons;
|
||||
late List<String> iconList;
|
||||
late List<String> items;
|
||||
|
||||
TextEditingController editingController = TextEditingController();
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
loadAssets();
|
||||
}
|
||||
|
||||
Future<List<String>> loadAssets() async {
|
||||
final manifestJson =
|
||||
await DefaultAssetBundle.of(context).loadString('AssetManifest.json');
|
||||
// ignore: no_leading_underscores_for_local_identifiers
|
||||
final _icons = await json
|
||||
.decode(manifestJson)
|
||||
.keys
|
||||
.where((String key) => key.startsWith('images/car_icons/'))
|
||||
.toList();
|
||||
setState(() {
|
||||
icons = _icons;
|
||||
items = _icons;
|
||||
});
|
||||
return _icons;
|
||||
}
|
||||
|
||||
void runFilter(String query) {
|
||||
List<String> results = [];
|
||||
if (query.isEmpty) {
|
||||
results = icons;
|
||||
} else {
|
||||
results = icons
|
||||
.where((i) => i.substring(17, i.length - 4).contains(query))
|
||||
.toList();
|
||||
}
|
||||
setState(() {
|
||||
items = results;
|
||||
});
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Dialog(
|
||||
child: Column(children: [
|
||||
Padding(
|
||||
padding: const EdgeInsets.all(8.0),
|
||||
child: TextField(
|
||||
decoration: const InputDecoration(
|
||||
prefixIcon: Icon(Icons.search),
|
||||
hintText: "Search icons",
|
||||
),
|
||||
onChanged: (value) {
|
||||
// filterSearch(value, iconList);
|
||||
runFilter(value);
|
||||
print('items found: $items');
|
||||
},
|
||||
// controller: editingController,
|
||||
),
|
||||
),
|
||||
Expanded(
|
||||
child: ListView.builder(
|
||||
itemCount: items.length,
|
||||
itemBuilder: (context, index) => ListTile(
|
||||
leading: CircleAvatar(
|
||||
// backgroundImage: AssetImage(iconList[index]),
|
||||
backgroundImage: AssetImage(items[index]),
|
||||
backgroundColor: Colors.white,
|
||||
),
|
||||
title: Text(items[index].substring(17, items[index].length - 4)),
|
||||
// title: Text(items[index]),
|
||||
onTap: () =>
|
||||
Navigator.of(context, rootNavigator: true).pop(items[index]),
|
||||
// onTap: (() => setState(() {
|
||||
// widget.selectedIcon = items[index];
|
||||
// })))),
|
||||
),
|
||||
)),
|
||||
]));
|
||||
}
|
||||
}
|
||||
@@ -4,3 +4,4 @@ export 'package:dash/screens/car_detail.dart';
|
||||
export 'package:dash/screens/car_edit.dart';
|
||||
export 'package:dash/screens/txn_new.dart';
|
||||
export 'package:dash/screens/txn_type.dart';
|
||||
export 'package:dash/screens/iconpicker.dart';
|
||||
|
||||
@@ -79,7 +79,14 @@ class _NewTxnScreenState extends State<NewTxnScreen> {
|
||||
decoration: const InputDecoration(
|
||||
labelText: 'Cost',
|
||||
),
|
||||
initialValue: "0",
|
||||
initialValue: "",
|
||||
onTap: () {
|
||||
final ft = TextEditingController();
|
||||
ft.clear();
|
||||
setState(() {
|
||||
ft.text = "";
|
||||
});
|
||||
},
|
||||
onSaved: (val) =>
|
||||
setState(() => txn.cost = double.parse(val ?? "0")),
|
||||
keyboardType: TextInputType.number,
|
||||
@@ -117,8 +124,6 @@ class _NewTxnScreenState extends State<NewTxnScreen> {
|
||||
setState(() {
|
||||
txn.datetime = DateTime.now().millisecondsSinceEpoch;
|
||||
txn.txntype = txnType.selectedText;
|
||||
print(
|
||||
"txntype set to ${txn.txntype} from radio ${txnType.selectedText}");
|
||||
txn.carid = car.id;
|
||||
car.mileage = txn.mileage; // update car mileage too
|
||||
});
|
||||
|
||||
@@ -32,7 +32,9 @@ class TxnTypeState extends State<TxnType> {
|
||||
|
||||
Widget rIcon(
|
||||
{required int index, required String text, required IconData icon}) {
|
||||
return Container(
|
||||
return AnimatedContainer(
|
||||
duration: const Duration(milliseconds: 300),
|
||||
curve: Curves.easeIn,
|
||||
padding: const EdgeInsets.all(16.0),
|
||||
decoration: BoxDecoration(
|
||||
shape: BoxShape.circle,
|
||||
|
||||
Reference in New Issue
Block a user