Home and Alarms page

This commit is contained in:
Igor Kulikov
2021-05-14 20:29:36 +03:00
parent 8e06f29694
commit ed654e46bd
41 changed files with 1112 additions and 534 deletions

View File

@@ -1,13 +1,22 @@
import 'dart:async';
import 'package:flutter/material.dart';
import 'package:flutter/widgets.dart';
import 'package:infinite_scroll_pagination/infinite_scroll_pagination.dart';
import 'package:intl/intl.dart';
import 'package:thingsboard_app/core/context/tb_context.dart';
import 'package:thingsboard_app/core/context/tb_context_widget.dart';
import 'package:thingsboard_client/thingsboard_client.dart';
typedef EntityDetailsFunction<T extends BaseData> = Function(T entity);
typedef EntityCardWidgetBuilder<T extends BaseData> = Widget Function(BuildContext context, T entity, bool briefView);
typedef EntityTapFunction<T> = Function(T entity);
typedef EntityCardWidgetBuilder<T> = Widget Function(BuildContext context, T entity);
mixin EntitiesBase<T extends BaseData> on HasTbContext {
class EntityCardSettings {
bool dropShadow;
EntityCardSettings({this.dropShadow = true});
}
mixin EntitiesBase<T, P> on HasTbContext {
final entityDateFormat = DateFormat('yyyy-MM-dd');
@@ -15,75 +24,255 @@ mixin EntitiesBase<T extends BaseData> on HasTbContext {
String get noItemsFoundText;
Future<PageData<T>> fetchEntities(PageLink pageLink);
Future<PageData<T>> fetchEntities(P pageKey);
Widget buildEntityCard(BuildContext context, T entity, bool briefView);
Future<void> onRefresh() => Future.value();
void onEntityDetails(T entity);
Widget? buildHeading(BuildContext context) => null;
Widget buildEntityListCard(BuildContext context, T entity) {
return Text('Not implemented!');
}
Widget buildEntityListWidgetCard(BuildContext context, T entity) {
return Text('Not implemented!');
}
Widget buildEntityGridCard(BuildContext context, T entity) {
return Text('Not implemented!');
}
P createFirstKey({int pageSize = 10}) => throw UnimplementedError('Not implemented');
P nextPageKey(P pageKey) => throw UnimplementedError('Not implemented');
EntityCardSettings entityListCardSettings(T entity) => EntityCardSettings();
EntityCardSettings entityGridCardSettings(T entity) => EntityCardSettings();
void onEntityTap(T entity);
}
class EntityCard<T extends BaseData> extends StatelessWidget {
final bool _briefView;
final T _entity;
final EntityDetailsFunction<T>? _onDetails;
final EntityCardWidgetBuilder<T> _entityCardWidgetBuilder;
mixin EntitiesBaseWithPageLink<T> on EntitiesBase<T, PageLink> {
EntityCard(T entity, {EntityDetailsFunction<T>? onDetails,
required EntityCardWidgetBuilder<T> entityCardWidgetBuilder,
required bool briefView}):
this._entity = entity,
this._onDetails = onDetails,
this._entityCardWidgetBuilder = entityCardWidgetBuilder,
this._briefView = briefView;
@override
PageLink createFirstKey({int pageSize = 10}) => PageLink(pageSize, 0, null, SortOrder('createdTime', Direction.DESC));
@override
PageLink nextPageKey(PageLink pageKey) => pageKey.nextPageLink();
}
mixin EntitiesBaseWithTimePageLink<T> on EntitiesBase<T, TimePageLink> {
@override
TimePageLink createFirstKey({int pageSize = 10}) => TimePageLink(pageSize, 0, null, SortOrder('createdTime', Direction.DESC));
@override
TimePageLink nextPageKey(TimePageLink pageKey) => pageKey.nextPageLink();
}
abstract class BaseEntitiesPageLinkWidget<T> extends BaseEntitiesWidget<T, PageLink> with EntitiesBaseWithPageLink<T> {
BaseEntitiesPageLinkWidget(TbContext tbContext): super(tbContext);
}
abstract class BaseEntitiesTimePageLinkWidget<T> extends BaseEntitiesWidget<T, TimePageLink> with EntitiesBaseWithTimePageLink<T> {
BaseEntitiesTimePageLinkWidget(TbContext tbContext): super(tbContext);
}
abstract class BaseEntitiesWidget<T, P> extends TbContextWidget<BaseEntitiesWidget<T, P>, BaseEntitiesState<T, P>> with EntitiesBase<T, P> {
BaseEntitiesWidget(TbContext tbContext): super(tbContext);
}
abstract class BaseEntitiesState<T, P> extends TbContextState<BaseEntitiesWidget<T, P>, BaseEntitiesState<T, P>> {
late final PagingController<P, T> pagingController;
Completer<void>? _refreshCompleter;
@override
void initState() {
super.initState();
pagingController = PagingController(firstPageKey: widget.createFirstKey());
pagingController.addPageRequestListener((pageKey) {
_fetchPage(pageKey);
});
}
@override
void dispose() {
pagingController.dispose();
super.dispose();
}
bool _dataLoading = false;
bool _scheduleRefresh = false;
Future<void> _refresh() {
if (_refreshCompleter == null) {
_refreshCompleter = Completer();
}
if (_dataLoading) {
_scheduleRefresh = true;
} else {
_refreshPagingController();
}
return _refreshCompleter!.future;
}
void _refreshPagingController() {
_fetchPage(widget.createFirstKey(), refresh: true);
}
Future<void> _fetchPage(P pageKey, {bool refresh = false}) async {
if (mounted) {
_dataLoading = true;
try {
hideNotification();
final pageData = await widget.fetchEntities(pageKey);
final isLastPage = !pageData.hasNext;
if (refresh) {
var state = pagingController.value;
if (state.itemList != null) {
state.itemList!.clear();
}
}
if (isLastPage) {
pagingController.appendLastPage(pageData.data);
} else {
final nextPageKey = widget.nextPageKey(pageKey);
pagingController.appendPage(pageData.data, nextPageKey);
}
} catch (error) {
if (mounted) {
pagingController.error = error;
}
} finally {
_dataLoading = false;
if (refresh) {
_refreshCompleter!.complete();
_refreshCompleter = null;
}
if (_scheduleRefresh) {
_scheduleRefresh = false;
if (mounted) {
_refreshPagingController();
}
}
}
}
}
@override
Widget build(BuildContext context) {
return
GestureDetector(
behavior: HitTestBehavior.opaque,
child:
Container(
height: 64,
margin: _briefView ? EdgeInsets.only(right: 8) : EdgeInsets.symmetric(vertical: 4, horizontal: 8),
child: Card(
margin: EdgeInsets.zero,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(_briefView ? 4 : 6),
),
elevation: 0,
child: Padding(
padding: const EdgeInsets.all(2),
child: _entityCardWidgetBuilder(context, _entity, _briefView)
)
return RefreshIndicator(
onRefresh: () => Future.wait([
widget.onRefresh(),
_refresh()
]),
child: pagedViewBuilder(context)
);
}
Widget pagedViewBuilder(BuildContext context);
Widget firstPageProgressIndicatorBuilder(BuildContext context) {
return Stack( children: [
Positioned(
top: 20,
left: 0,
right: 0,
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [RefreshProgressIndicator()],
),
)
]);
}
Widget newPageProgressIndicatorBuilder(BuildContext context) {
return Padding(
padding: const EdgeInsets.only(
top: 16,
bottom: 16,
),
child: Center(child: RefreshProgressIndicator()),
);
}
Widget noItemsFoundIndicatorBuilder(BuildContext context) {
return FirstPageExceptionIndicator(
title: widget.noItemsFoundText,
message: 'The list is currently empty.',
onTryAgain: () => pagingController.refresh(),
);
}
}
class FirstPageExceptionIndicator extends StatelessWidget {
const FirstPageExceptionIndicator({
required this.title,
this.message,
this.onTryAgain,
Key? key,
}) : super(key: key);
final String title;
final String? message;
final VoidCallback? onTryAgain;
@override
Widget build(BuildContext context) {
final message = this.message;
return Center(
child: Padding(
padding: const EdgeInsets.symmetric(vertical: 32, horizontal: 16),
child: Column(
children: [
Text(
title,
textAlign: TextAlign.center,
style: Theme.of(context).textTheme.headline6,
),
decoration: _briefView ? BoxDecoration(
border: Border.all(
color: Color(0xFFDEDEDE),
style: BorderStyle.solid,
width: 1
if (message != null)
const SizedBox(
height: 16,
),
if (message != null)
Text(
message,
textAlign: TextAlign.center,
),
if (onTryAgain != null)
const SizedBox(
height: 48,
),
if (onTryAgain != null)
SizedBox(
height: 50,
width: double.infinity,
child: ElevatedButton.icon(
onPressed: onTryAgain,
icon: const Icon(
Icons.refresh,
color: Colors.white,
),
label: const Text(
'Try Again',
style: TextStyle(
fontSize: 16,
color: Colors.white,
),
),
),
borderRadius: BorderRadius.circular(4)
) : BoxDecoration(
boxShadow: [
BoxShadow(
color: Colors.black.withAlpha(25),
blurRadius: 10.0,
offset: Offset(0, 4)
),
BoxShadow(
color: Colors.black.withAlpha(18),
blurRadius: 30.0,
offset: Offset(0, 10)
),
],
),
),
onTap: () {
if (_onDetails != null) {
_onDetails!(_entity);
}
}
);
),
],
),
),
);
}
}

View File

@@ -0,0 +1,58 @@
import 'package:flutter/material.dart';
import 'package:flutter/widgets.dart';
import 'package:infinite_scroll_pagination/infinite_scroll_pagination.dart';
import 'entities_base.dart';
import 'entity_grid_card.dart';
mixin EntitiesGridStateBase on StatefulWidget {
@override
_EntitiesGridState createState() => _EntitiesGridState();
}
class _EntitiesGridState<T, P> extends BaseEntitiesState<T, P> {
@override
Widget pagedViewBuilder(BuildContext context) {
var heading = widget.buildHeading(context);
List<Widget> slivers = [];
if (heading != null) {
slivers.add(SliverPadding(
padding: EdgeInsets.fromLTRB(16, 16, 16, 0),
sliver: SliverToBoxAdapter(
child: heading
)));
}
slivers.add(SliverPadding(
padding: EdgeInsets.all(16),
sliver: PagedSliverGrid(
showNewPageProgressIndicatorAsGridChild: false,
showNewPageErrorIndicatorAsGridChild: false,
showNoMoreItemsIndicatorAsGridChild: false,
pagingController: pagingController,
// padding: EdgeInsets.all(16),
gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(
childAspectRatio: 156 / 150,
crossAxisSpacing: 16,
mainAxisSpacing: 16,
crossAxisCount: 2,
),
builderDelegate: PagedChildBuilderDelegate<T>(
itemBuilder: (context, item, index) => EntityGridCard<T>(
item,
entityCardWidgetBuilder: widget.buildEntityGridCard,
onEntityTap: widget.onEntityTap,
settings: widget.entityGridCardSettings(item),
),
firstPageProgressIndicatorBuilder: firstPageProgressIndicatorBuilder,
newPageProgressIndicatorBuilder: newPageProgressIndicatorBuilder,
noItemsFoundIndicatorBuilder: noItemsFoundIndicatorBuilder
)
)));
return CustomScrollView(
slivers: slivers
);
}
}

View File

@@ -0,0 +1,49 @@
import 'package:flutter/material.dart';
import 'package:flutter/widgets.dart';
import 'package:infinite_scroll_pagination/infinite_scroll_pagination.dart';
import 'package:thingsboard_app/core/entity/entities_base.dart';
import 'entity_list_card.dart';
mixin EntitiesListStateBase on StatefulWidget {
@override
_EntitiesListState createState() => _EntitiesListState();
}
class _EntitiesListState<T,P> extends BaseEntitiesState<T, P> {
@override
Widget pagedViewBuilder(BuildContext context) {
var heading = widget.buildHeading(context);
List<Widget> slivers = [];
if (heading != null) {
slivers.add(SliverPadding(
padding: EdgeInsets.fromLTRB(16, 16, 16, 0),
sliver: SliverToBoxAdapter(
child: heading
)));
}
slivers.add(SliverPadding(
padding: EdgeInsets.all(16),
sliver: PagedSliverList.separated(
pagingController: pagingController,
separatorBuilder: (context, index) => SizedBox(height: 8),
builderDelegate: PagedChildBuilderDelegate<T>(
itemBuilder: (context, item, index) => EntityListCard<T>(
item,
entityCardWidgetBuilder: widget.buildEntityListCard,
onEntityTap: widget.onEntityTap,
settings: widget.entityListCardSettings(item),
),
firstPageProgressIndicatorBuilder: firstPageProgressIndicatorBuilder,
newPageProgressIndicatorBuilder: newPageProgressIndicatorBuilder,
noItemsFoundIndicatorBuilder: noItemsFoundIndicatorBuilder
)
)));
return CustomScrollView(
slivers: slivers
);
}
}

View File

@@ -3,22 +3,23 @@ import 'dart:async';
import 'package:fading_edge_scrollview/fading_edge_scrollview.dart';
import 'package:flutter/material.dart';
import 'package:flutter/widgets.dart';
import 'package:intl/intl.dart';
import 'package:thingsboard_app/core/context/tb_context.dart';
import 'package:thingsboard_app/core/context/tb_context_widget.dart';
import 'package:thingsboard_app/core/entity/entities_base.dart';
import 'package:thingsboard_client/thingsboard_client.dart';
class EntitiesWidgetController {
import 'entity_list_card.dart';
final List<_EntitiesWidgetState> states = [];
class EntitiesListWidgetController {
void _registerEntitiesWidgetState(_EntitiesWidgetState entitiesWidgetState) {
states.add(entitiesWidgetState);
final List<_EntitiesListWidgetState> states = [];
void _registerEntitiesWidgetState(_EntitiesListWidgetState entitiesListWidgetState) {
states.add(entitiesListWidgetState);
}
void _unregisterEntitiesWidgetState(_EntitiesWidgetState entitiesWidgetState) {
states.remove(entitiesWidgetState);
void _unregisterEntitiesWidgetState(_EntitiesListWidgetState entitiesListWidgetState) {
states.remove(entitiesListWidgetState);
}
Future<void> refresh() {
@@ -31,29 +32,32 @@ class EntitiesWidgetController {
}
abstract class EntitiesWidget<T extends BaseData> extends TbContextWidget<EntitiesWidget<T>, _EntitiesWidgetState<T>> with EntitiesBase<T> {
abstract class EntitiesListPageLinkWidget<T> extends EntitiesListWidget<T, PageLink> with EntitiesBaseWithPageLink<T> {
EntitiesListPageLinkWidget(TbContext tbContext, {EntitiesListWidgetController? controller}): super(tbContext, controller: controller);
}
final entityDateFormat = DateFormat('yyyy-MM-dd');
final EntitiesWidgetController? _controller;
abstract class EntitiesListWidget<T, P> extends TbContextWidget<EntitiesListWidget<T,P>, _EntitiesListWidgetState<T,P>> with EntitiesBase<T,P> {
EntitiesWidget(TbContext tbContext, {EntitiesWidgetController? controller}):
final EntitiesListWidgetController? _controller;
EntitiesListWidget(TbContext tbContext, {EntitiesListWidgetController? controller}):
_controller = controller,
super(tbContext);
@override
_EntitiesWidgetState createState() => _EntitiesWidgetState(_controller);
_EntitiesListWidgetState createState() => _EntitiesListWidgetState(_controller);
void onViewAll();
}
class _EntitiesWidgetState<T extends BaseData> extends TbContextState<EntitiesWidget<T>, _EntitiesWidgetState<T>> {
class _EntitiesListWidgetState<T,P> extends TbContextState<EntitiesListWidget<T,P>, _EntitiesListWidgetState<T,P>> {
final EntitiesWidgetController? _controller;
final EntitiesListWidgetController? _controller;
final StreamController<PageData<T>?> _entitiesStreamController = StreamController.broadcast();
_EntitiesWidgetState(EntitiesWidgetController? controller):
_EntitiesListWidgetState(EntitiesListWidgetController? controller):
_controller = controller;
@override
@@ -76,7 +80,7 @@ class _EntitiesWidgetState<T extends BaseData> extends TbContextState<EntitiesWi
Future<void> _refresh() {
_entitiesStreamController.add(null);
var entitiesFuture = widget.fetchEntities(PageLink(5, 0, null, SortOrder('createdTime', Direction.DESC)));
var entitiesFuture = widget.fetchEntities(widget.createFirstKey(pageSize: 5));
entitiesFuture.then((value) => _entitiesStreamController.add(value));
return entitiesFuture;
}
@@ -204,11 +208,12 @@ class _EntitiesWidgetState<T extends BaseData> extends TbContextState<EntitiesWi
child: ListView(
scrollDirection: Axis.horizontal,
controller: ScrollController(),
children: entities.map((entity) => EntityCard<T>(
children: entities.map((entity) => EntityListCard<T>(
entity,
entityCardWidgetBuilder: widget.buildEntityCard,
onDetails: widget.onEntityDetails,
briefView: true
entityCardWidgetBuilder: widget.buildEntityListWidgetCard,
onEntityTap: widget.onEntityTap,
settings: widget.entityListCardSettings(entity),
listWidgetCard: true
)).toList()
));
}

View File

@@ -1,220 +0,0 @@
import 'package:flutter/material.dart';
import 'package:flutter/widgets.dart';
import 'package:infinite_scroll_pagination/infinite_scroll_pagination.dart';
import 'package:thingsboard_app/core/context/tb_context.dart';
import 'package:thingsboard_app/core/context/tb_context_widget.dart';
import 'package:thingsboard_app/core/entity/entities_base.dart';
import 'package:thingsboard_app/widgets/tb_app_bar.dart';
import 'package:thingsboard_client/thingsboard_client.dart';
abstract class EntitiesPage<T extends BaseData> extends TbContextWidget<EntitiesPage<T>, _EntitiesPageState<T>> with EntitiesBase<T> {
EntitiesPage(TbContext tbContext): super(tbContext);
String get searchHint;
String get noMoreItemsText;
@override
_EntitiesPageState createState() => _EntitiesPageState();
}
class _EntitiesPageState<T extends BaseData> extends TbContextState<EntitiesPage<T>, _EntitiesPageState<T>> {
final _searchModeNotifier = ValueNotifier<bool>(false);
final PagingController<PageLink, T> _pagingController = PagingController(firstPageKey: PageLink(10, 0, null, SortOrder('createdTime', Direction.DESC)));
@override
void initState() {
super.initState();
_pagingController.addPageRequestListener((pageKey) {
_fetchPage(pageKey);
});
}
@override
void dispose() {
_pagingController.dispose();
super.dispose();
}
bool _dataLoading = false;
bool _scheduleRefresh = false;
void _refresh() {
if (_dataLoading) {
_scheduleRefresh = true;
} else {
_pagingController.refresh();
}
}
Future<void> _fetchPage(PageLink pageKey) async {
if (mounted) {
_dataLoading = true;
try {
hideNotification();
final pageData = await widget.fetchEntities(pageKey);
final isLastPage = !pageData.hasNext;
if (isLastPage) {
_pagingController.appendLastPage(pageData.data);
} else {
final nextPageKey = pageKey.nextPageLink();
_pagingController.appendPage(pageData.data, nextPageKey);
}
} catch (error) {
if (mounted) {
_pagingController.error = error;
}
} finally {
_dataLoading = false;
if (_scheduleRefresh) {
_scheduleRefresh = false;
if (mounted) {
_pagingController.refresh();
}
}
}
}
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: TbAppBar(
tbContext,
title: Text(widget.title),
searchModeNotifier: _searchModeNotifier,
searchHint: widget.searchHint,
onSearch: (String searchText) {
_pagingController.firstPageKey.textSearch = searchText;
_pagingController.firstPageKey.page = 0;
_refresh();
},
),
body: RefreshIndicator(
onRefresh: () => Future.sync(
() => _refresh(),
),
child: PagedListView(
pagingController: _pagingController,
padding: EdgeInsets.all(0),
builderDelegate: PagedChildBuilderDelegate<T>(
itemBuilder: (context, item, index) => EntityCard<T>(
item,
entityCardWidgetBuilder: widget.buildEntityCard,
onDetails: widget.onEntityDetails,
briefView: false
),
firstPageProgressIndicatorBuilder: (context) {
return Stack( children: [
Positioned(
top: 20,
left: 0,
right: 0,
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [RefreshProgressIndicator()],
),
)
]);
},
newPageProgressIndicatorBuilder: (context) {
return Padding(
padding: const EdgeInsets.only(
top: 16,
bottom: 16,
),
child: Center(child: RefreshProgressIndicator()),
);
},
noItemsFoundIndicatorBuilder: (context) => FirstPageExceptionIndicator(
title: widget.noItemsFoundText,
message: 'The list is currently empty.',
onTryAgain: () => _refresh(),
)
)
)
)
/* bottomNavigationBar: BottomAppBar(
child: Row(
children: [
IconButton(icon: Icon(Icons.refresh), onPressed: () {
_refresh();
}),
Spacer(),
IconButton(icon: Icon(Icons.search), onPressed: () {
_searchModeNotifier.value = true;
})
]
)
) */
);
}
}
class FirstPageExceptionIndicator extends StatelessWidget {
const FirstPageExceptionIndicator({
required this.title,
this.message,
this.onTryAgain,
Key? key,
}) : super(key: key);
final String title;
final String? message;
final VoidCallback? onTryAgain;
@override
Widget build(BuildContext context) {
final message = this.message;
return Center(
child: Padding(
padding: const EdgeInsets.symmetric(vertical: 32, horizontal: 16),
child: Column(
children: [
Text(
title,
textAlign: TextAlign.center,
style: Theme.of(context).textTheme.headline6,
),
if (message != null)
const SizedBox(
height: 16,
),
if (message != null)
Text(
message,
textAlign: TextAlign.center,
),
if (onTryAgain != null)
const SizedBox(
height: 48,
),
if (onTryAgain != null)
SizedBox(
height: 50,
width: double.infinity,
child: ElevatedButton.icon(
onPressed: onTryAgain,
icon: const Icon(
Icons.refresh,
color: Colors.white,
),
label: const Text(
'Try Again',
style: TextStyle(
fontSize: 16,
color: Colors.white,
),
),
),
),
],
),
),
);
}
}

View File

@@ -0,0 +1,63 @@
import 'package:flutter/material.dart';
import 'package:flutter/widgets.dart';
import 'package:thingsboard_client/thingsboard_client.dart';
import 'entities_base.dart';
class EntityGridCard<T> extends StatelessWidget {
final T _entity;
final EntityTapFunction<T>? _onEntityTap;
final EntityCardWidgetBuilder<T> _entityCardWidgetBuilder;
final EntityCardSettings _settings;
EntityGridCard(T entity, {EntityTapFunction<T>? onEntityTap,
required EntityCardWidgetBuilder<T> entityCardWidgetBuilder,
required EntityCardSettings settings}):
this._entity = entity,
this._onEntityTap = onEntityTap,
this._entityCardWidgetBuilder = entityCardWidgetBuilder,
this._settings = settings;
@override
Widget build(BuildContext context) {
return
GestureDetector(
behavior: HitTestBehavior.opaque,
child:
Container(
child: Card(
margin: EdgeInsets.zero,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(10),
),
elevation: 0,
child: Padding(
padding: const EdgeInsets.all(4),
child: _entityCardWidgetBuilder(context, _entity)
)
),
decoration: _settings.dropShadow ? BoxDecoration(
boxShadow: [
BoxShadow(
color: Colors.black.withAlpha(25),
blurRadius: 10.0,
offset: Offset(0, 4)
),
BoxShadow(
color: Colors.black.withAlpha(18),
blurRadius: 30.0,
offset: Offset(0, 10)
),
],
) : null,
),
onTap: () {
if (_onEntityTap != null) {
_onEntityTap!(_entity);
}
}
);
}
}

View File

@@ -0,0 +1,73 @@
import 'package:flutter/material.dart';
import 'package:flutter/widgets.dart';
import 'entities_base.dart';
class EntityListCard<T> extends StatelessWidget {
final bool _listWidgetCard;
final T _entity;
final EntityTapFunction<T>? _onEntityTap;
final EntityCardWidgetBuilder<T> _entityCardWidgetBuilder;
final EntityCardSettings _settings;
EntityListCard(T entity, {EntityTapFunction<T>? onEntityTap,
required EntityCardWidgetBuilder<T> entityCardWidgetBuilder,
required EntityCardSettings settings,
bool listWidgetCard = false}):
this._entity = entity,
this._onEntityTap = onEntityTap,
this._entityCardWidgetBuilder = entityCardWidgetBuilder,
this._settings = settings,
this._listWidgetCard = listWidgetCard;
@override
Widget build(BuildContext context) {
return
GestureDetector(
behavior: HitTestBehavior.opaque,
child:
Container(
margin: _listWidgetCard ? EdgeInsets.only(right: 8) : EdgeInsets.zero,
child: Card(
margin: EdgeInsets.zero,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(_listWidgetCard ? 4 : 6),
),
elevation: 0,
child: Padding(
padding: const EdgeInsets.all(2),
child: _entityCardWidgetBuilder(context, _entity)
)
),
decoration: _listWidgetCard ? BoxDecoration(
border: Border.all(
color: Color(0xFFDEDEDE),
style: BorderStyle.solid,
width: 1
),
borderRadius: BorderRadius.circular(4)
) : BoxDecoration(
boxShadow: [
BoxShadow(
color: Colors.black.withAlpha(25),
blurRadius: 10.0,
offset: Offset(0, 4)
),
BoxShadow(
color: Colors.black.withAlpha(18),
blurRadius: 30.0,
offset: Offset(0, 10)
),
],
),
),
onTap: () {
if (_onEntityTap != null) {
_onEntityTap!(_entity);
}
}
);
}
}