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