AppBar
s 底部属性是 type PreferredSizeWidget
,所以我提供PreferredSize
了需要在preferredSize
属性中指定要使用的实际大小的小部件。但我不需要静态数字,而是根据孩子自动计算,在我的例子中是Wrap
小部件。问题是只有在使用调用方法Wrap
后才能确定高度。build
RenderObject
我有的:
我想要的(由gif编辑软件制作):
代码:
import 'package:flutter/material.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatefulWidget {
_MyAppState createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
final items = List.generate(400, (index) => '$index');
final filterOptions = <IntType>[];
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
body: buildBody(),
appBar: AppBar(
title: Text('Simple filtering'),
bottom: buildAppBarBottom(),
),
),
);
}
Widget buildBody() {
return Scrollbar(
child: ListView.builder(
itemCount: items.length,
itemBuilder: (context, index) {
final item = items[index];
if (filterOptions.every((option) => item.contains(option.symbol))) {
return ListTile(title: Text(item));
}
return Container(height: 0.0001);
},
),
);
}
PreferredSizeWidget buildAppBarBottom() {
return PreferredSize(
preferredSize: Size.fromHeight(100), // change height depending on the child height
child: Wrap(
spacing: 8,
children: IntType.values.map((option) {
return FilterChip(
selectedColor: Colors.white,
selected: filterOptions.contains(option),
onSelected: (isSelected) {
setState(() {
if (isSelected) {
filterOptions.add(option);
} else {
filterOptions.remove(option);
}
});
},
label: Text(option.name),
);
}).toList(),
),
);
}
}
class IntType {
static const IntType one = const IntType._('One', '1');
static const IntType two = const IntType._('Two', '2');
static const IntType three = const IntType._('Three', '3');
static const IntType four = const IntType._('Four', '4');
static const IntType five = const IntType._('Five', '5');
static const IntType six = const IntType._('Six', '6');
static const IntType seven = const IntType._('Seven', '7');
static const IntType eight = const IntType._('Eight', '8');
static const IntType nine = const IntType._('Nine', '9');
static const IntType zero = const IntType._('Zero', '0');
final String name;
final String symbol;
const IntType._(this.name, this.symbol);
static const values = [
IntType.one,
IntType.two,
IntType.three,
IntType.four,
IntType.five,
IntType.six,
IntType.seven,
IntType.eight,
IntType.nine,
IntType.zero,
];
}
编辑:
Wrap
感谢 AKS 的回答 解决方法是移到Scaffold
's body
更新代码:
import 'package:flutter/material.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatefulWidget {
_MyAppState createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
final items = List.generate(400, (index) => '$index');
final filterOptions = <IntType>[];
@override
Widget build(BuildContext context) {
return MaterialApp(
theme: ThemeData(appBarTheme: AppBarTheme(elevation: 0)),
home: Scaffold(
body: buildBody(),
appBar: AppBar(
title: Text('Simple filtering'),
),
),
);
}
Widget buildBody() {
return Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
Material(
elevation: 4,
child: Container(
color: Theme.of(context).primaryColor,
child: Padding(
padding: const EdgeInsets.all(8.0),
child: Wrap(
alignment: WrapAlignment.center,
spacing: 8,
children: IntType.values.map((option) {
return FilterChip(
selectedColor: Colors.white,
selected: filterOptions.contains(option),
onSelected: (isSelected) {
setState(() {
if (isSelected) {
filterOptions.add(option);
} else {
filterOptions.remove(option);
}
});
},
label: Text(option.name),
);
}).toList(),
),
),
),
),
Expanded(
child: Scrollbar(
child: ListView.builder(
itemCount: items.length,
itemBuilder: (context, index) {
final item = items[index];
if (filterOptions
.every((option) => item.contains(option.symbol))) {
return ListTile(title: Text(item));
}
return Container(height: 0.0001);
},
),
),
),
],
);
}
}
class IntType {
static const IntType one = const IntType._('One', '1');
static const IntType two = const IntType._('Two', '2');
static const IntType three = const IntType._('Three', '3');
static const IntType four = const IntType._('Four', '4');
static const IntType five = const IntType._('Five', '5');
static const IntType six = const IntType._('Six', '6');
static const IntType seven = const IntType._('Seven', '7');
static const IntType eight = const IntType._('Eight', '8');
static const IntType nine = const IntType._('Nine', '9');
static const IntType zero = const IntType._('Zero', '0');
final String name;
final String symbol;
const IntType._(this.name, this.symbol);
static const values = [
IntType.one,
IntType.two,
IntType.three,
IntType.four,
IntType.five,
IntType.six,
IntType.seven,
IntType.eight,
IntType.nine,
IntType.zero,
];
}