From 7f32ef4bf16d140ce618099ea4f3cc4e3895f98e Mon Sep 17 00:00:00 2001 From: Jonas Franz Date: Thu, 17 Feb 2022 12:06:37 +0100 Subject: [PATCH] Add product list --- lib/app.dart | 2 +- lib/models/product.dart | 11 ++++ .../product_list/ProductListScreen.dart | 12 ----- lib/screens/product_list/product_item.dart | 16 ++++++ .../product_list/product_list_screen.dart | 27 ++++++++++ lib/widgets/number_picker.dart | 52 +++++++++++++++++++ 6 files changed, 107 insertions(+), 13 deletions(-) create mode 100644 lib/models/product.dart delete mode 100644 lib/screens/product_list/ProductListScreen.dart create mode 100644 lib/screens/product_list/product_item.dart create mode 100644 lib/screens/product_list/product_list_screen.dart create mode 100644 lib/widgets/number_picker.dart diff --git a/lib/app.dart b/lib/app.dart index b391332..62b0ce4 100644 --- a/lib/app.dart +++ b/lib/app.dart @@ -1,5 +1,5 @@ import 'package:flutter/material.dart'; -import 'package:thesis_shop/screens/product_list/ProductListScreen.dart'; +import 'package:thesis_shop/screens/product_list/product_list_screen.dart'; class ThesisShopApp extends StatelessWidget { const ThesisShopApp({Key? key}) : super(key: key); diff --git a/lib/models/product.dart b/lib/models/product.dart new file mode 100644 index 0000000..1b73556 --- /dev/null +++ b/lib/models/product.dart @@ -0,0 +1,11 @@ +import 'package:flutter/foundation.dart'; + +@immutable +class Product { + final String title; + final double price; + + String get priceAsString => price.toStringAsFixed(2); + + const Product({required this.title, required this.price}); +} diff --git a/lib/screens/product_list/ProductListScreen.dart b/lib/screens/product_list/ProductListScreen.dart deleted file mode 100644 index 37adc34..0000000 --- a/lib/screens/product_list/ProductListScreen.dart +++ /dev/null @@ -1,12 +0,0 @@ -import 'package:flutter/material.dart'; - -class ProductListScreen extends StatelessWidget { - const ProductListScreen({Key? key}) : super(key: key); - - @override - Widget build(BuildContext context) { - return Scaffold( - appBar: AppBar(title: const Text('Thesis Shop')), - ); - } -} diff --git a/lib/screens/product_list/product_item.dart b/lib/screens/product_list/product_item.dart new file mode 100644 index 0000000..62e813d --- /dev/null +++ b/lib/screens/product_list/product_item.dart @@ -0,0 +1,16 @@ +import 'package:flutter/material.dart'; +import 'package:thesis_shop/models/product.dart'; +import 'package:thesis_shop/widgets/number_picker.dart'; + +class ProductItem extends StatelessWidget { + final Product product; + const ProductItem({Key? key, required this.product}) : super(key: key); + + @override + Widget build(BuildContext context) { + return ListTile( + title: Text('${product.title} (${product.priceAsString}€/Stück)'), + trailing: NumberPicker(value: 5, onUp: () {}, onDown: () {}), + ); + } +} diff --git a/lib/screens/product_list/product_list_screen.dart b/lib/screens/product_list/product_list_screen.dart new file mode 100644 index 0000000..9258fa3 --- /dev/null +++ b/lib/screens/product_list/product_list_screen.dart @@ -0,0 +1,27 @@ +import 'package:flutter/material.dart'; +import 'package:thesis_shop/models/product.dart'; +import 'package:thesis_shop/screens/product_list/product_item.dart'; + +const _productPlaceholder = [ + Product(title: 'Bananen', price: 3), + Product(title: 'Äpfel', price: 2), + Product(title: 'Birnen', price: 2.5), + Product(title: 'Kirschen', price: 1.2), +]; + +class ProductListScreen extends StatelessWidget { + const ProductListScreen({Key? key}) : super(key: key); + + @override + Widget build(BuildContext context) { + const products = _productPlaceholder; + return Scaffold( + appBar: AppBar(title: const Text('Thesis Shop')), + body: ListView.separated( + itemCount: products.length, + itemBuilder: (context, index) => ProductItem(product: products[index]), + separatorBuilder: (context, _) => const Divider(), + ), + ); + } +} diff --git a/lib/widgets/number_picker.dart b/lib/widgets/number_picker.dart new file mode 100644 index 0000000..f301588 --- /dev/null +++ b/lib/widgets/number_picker.dart @@ -0,0 +1,52 @@ +import 'package:flutter/material.dart'; + +class NumberPicker extends StatelessWidget { + final int value; + final VoidCallback onUp; + final VoidCallback onDown; + final int minValue; + final int maxValue; + const NumberPicker({ + Key? key, + required this.value, + required this.onUp, + required this.onDown, + this.minValue = 0, + this.maxValue = 100, + }) : super(key: key); + + @override + Widget build(BuildContext context) { + return Row( + mainAxisSize: MainAxisSize.min, + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + _ConditionalIconButton( + enabled: value > minValue, onClick: onDown, iconData: Icons.remove), + Text(value.toString()), + _ConditionalIconButton( + enabled: value < maxValue, onClick: onUp, iconData: Icons.add), + ], + ); + } +} + +class _ConditionalIconButton extends StatelessWidget { + final bool enabled; + final VoidCallback onClick; + final IconData iconData; + const _ConditionalIconButton({ + Key? key, + required this.enabled, + required this.onClick, + required this.iconData, + }) : super(key: key); + + @override + Widget build(BuildContext context) { + return IconButton( + onPressed: enabled ? onClick : null, + icon: Icon(iconData), + ); + } +}