#277 filter chip max width extends when single
This commit is contained in:
parent
f74d02a8a7
commit
6f15b359b0
2 changed files with 64 additions and 17 deletions
|
@ -1,10 +1,12 @@
|
|||
import 'package:aves/model/filters/filters.dart';
|
||||
import 'package:aves/theme/durations.dart';
|
||||
import 'package:aves/widgets/common/identity/aves_app_bar.dart';
|
||||
import 'package:aves/widgets/common/identity/aves_filter_chip.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
class FilterBar extends StatefulWidget {
|
||||
static const EdgeInsets chipPadding = EdgeInsets.symmetric(horizontal: 4);
|
||||
static const EdgeInsets rowPadding = EdgeInsets.symmetric(horizontal: 4);
|
||||
static const double verticalPadding = 16;
|
||||
static const double preferredHeight = AvesFilterChip.minChipHeight + verticalPadding;
|
||||
|
||||
|
@ -27,6 +29,8 @@ class _FilterBarState extends State<FilterBar> {
|
|||
final GlobalKey<AnimatedListState> _animatedListKey = GlobalKey(debugLabel: 'filter-bar-animated-list');
|
||||
CollectionFilter? _userTappedFilter;
|
||||
|
||||
List<CollectionFilter> get filters => widget.filters;
|
||||
|
||||
FilterCallback? get onTap => widget.onTap;
|
||||
|
||||
@override
|
||||
|
@ -87,33 +91,64 @@ class _FilterBarState extends State<FilterBar> {
|
|||
onNotification: (notification) => true,
|
||||
child: AnimatedList(
|
||||
key: _animatedListKey,
|
||||
initialItemCount: widget.filters.length,
|
||||
initialItemCount: filters.length,
|
||||
scrollDirection: Axis.horizontal,
|
||||
padding: FilterBar.chipPadding,
|
||||
padding: FilterBar.rowPadding,
|
||||
itemBuilder: (context, index, animation) {
|
||||
if (index >= widget.filters.length) return const SizedBox();
|
||||
return _buildChip(widget.filters.toList()[index]);
|
||||
if (index >= filters.length) return const SizedBox();
|
||||
return _buildChip(filters.toList()[index]);
|
||||
},
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Padding _buildChip(CollectionFilter filter) {
|
||||
Widget _buildChip(CollectionFilter filter) {
|
||||
return _Chip(
|
||||
filter: filter,
|
||||
removable: widget.removable,
|
||||
single: filters.length == 1,
|
||||
onTap: onTap != null
|
||||
? (filter) {
|
||||
_userTappedFilter = filter;
|
||||
onTap!(filter);
|
||||
}
|
||||
: null,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class _Chip extends StatelessWidget {
|
||||
final CollectionFilter filter;
|
||||
final bool removable, single;
|
||||
final FilterCallback? onTap;
|
||||
|
||||
const _Chip({
|
||||
required this.filter,
|
||||
required this.removable,
|
||||
required this.single,
|
||||
required this.onTap,
|
||||
});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Padding(
|
||||
padding: FilterBar.chipPadding,
|
||||
child: Center(
|
||||
child: AvesFilterChip(
|
||||
key: ValueKey(filter),
|
||||
filter: filter,
|
||||
removable: widget.removable,
|
||||
heroType: HeroType.always,
|
||||
onTap: onTap != null
|
||||
? (filter) {
|
||||
_userTappedFilter = filter;
|
||||
onTap!(filter);
|
||||
}
|
||||
removable: removable,
|
||||
maxWidth: single
|
||||
? AvesFilterChip.computeMaxWidth(
|
||||
context,
|
||||
minChipPerRow: 1,
|
||||
chipPadding: FilterBar.chipPadding.horizontal,
|
||||
rowPadding: FilterBar.rowPadding.horizontal + AvesFloatingBar.margin.horizontal,
|
||||
)
|
||||
: null,
|
||||
heroType: HeroType.always,
|
||||
onTap: onTap,
|
||||
),
|
||||
),
|
||||
);
|
||||
|
|
|
@ -79,6 +79,17 @@ class AvesFilterChip extends StatefulWidget {
|
|||
this.onLongPress = showDefaultLongPressMenu,
|
||||
});
|
||||
|
||||
static double computeMaxWidth(
|
||||
BuildContext context, {
|
||||
required int minChipPerRow,
|
||||
required double chipPadding,
|
||||
required double rowPadding,
|
||||
}) {
|
||||
return context.select<MediaQueryData, double>((mq) {
|
||||
return (mq.size.width - mq.padding.horizontal - chipPadding * minChipPerRow - rowPadding) / minChipPerRow;
|
||||
});
|
||||
}
|
||||
|
||||
static Future<void> showDefaultLongPressMenu(BuildContext context, CollectionFilter filter, Offset tapPosition) async {
|
||||
if (context.read<ValueNotifier<AppMode>>().value.canNavigate) {
|
||||
final actions = [
|
||||
|
@ -266,11 +277,12 @@ class _AvesFilterChipState extends State<AvesFilterChip> {
|
|||
maxWidth: max(
|
||||
AvesFilterChip.minChipWidth,
|
||||
widget.maxWidth ??
|
||||
context.select<MediaQueryData, double>((mq) {
|
||||
const minChipPerRow = 2;
|
||||
final padding = FilterBar.chipPadding.horizontal;
|
||||
return (mq.size.width - mq.padding.horizontal - padding * (minChipPerRow + 1)) / minChipPerRow;
|
||||
})),
|
||||
AvesFilterChip.computeMaxWidth(
|
||||
context,
|
||||
minChipPerRow: 2,
|
||||
chipPadding: FilterBar.chipPadding.horizontal,
|
||||
rowPadding: FilterBar.rowPadding.horizontal,
|
||||
)),
|
||||
minHeight: AvesFilterChip.minChipHeight,
|
||||
),
|
||||
child: Stack(
|
||||
|
|
Loading…
Reference in a new issue