如何在appbar底部放置线性进度条?
how to position linear progress bar at appbar bottom?
如何在不使用应用栏底部 属性 且不增加应用栏高度的情况下将线性进度条放置在应用栏底部?
喜欢下图:
Material design appbar
只需使用 LinearProgressIndicator()
作为 column
中的第一个小部件。然后你会在 Appbar
下面看到进度条
return Scaffold(
appbar: Appbar(
title: Text('App Bar'),),
body: Column(
children: <widget> [
linearProgressIndicator(),
Text('Hi'),]
),
)
为什么不想用底部属性?这就是 Flutter AppBar
小部件提供的用于在其中添加内容的钩子。否则,您必须创建自己的 AppBar
.
版本
如果它对你有用,我创建了下面的代码片段,你可以像这样在你的应用栏中使用它。
appBar: new AppBar(
title: new Text("Title"),
backgroundColor: Colors.orange,
bottom: MyLinearProgressIndicator(
backgroundColor: Colors.orange,
),
),
MyLinearProgressIndicator
必须实施 preferredSize
getter。这就是为什么您需要创建自己的版本。
// Cant't use _kLinearProgressIndicatorHeight 'cause it is private in the
// progress_indicator.dart file
const double _kMyLinearProgressIndicatorHeight = 6.0;
class MyLinearProgressIndicator extends LinearProgressIndicator
implements PreferredSizeWidget {
MyLinearProgressIndicator({
Key key,
double value,
Color backgroundColor,
Animation<Color> valueColor,
}) : super(
key: key,
value: value,
backgroundColor: backgroundColor,
valueColor: valueColor,
) {
preferredSize = Size(double.infinity, _kMyLinearProgressIndicatorHeight);
}
@override
Size preferredSize;
}
这是结果:
@chemolins 的回答是完全有效的,但将小部件包装在 Preferred Size 小部件中可能更容易。该小部件采用 child
和类型 Size
的 preferredSize
这是我正在处理的应用程序的示例,包装了 StreamBuilder:
return Scaffold(
appBar: AppBar(
bottom: PreferredSize(
preferredSize: Size(double.infinity, 1.0),
child: ProgressBar(widget.bloc.isLoading),
),
---snip---
class ProgressBar extends StatelessWidget {
final Stream<bool> _isLoading;
ProgressBar(this._isLoading);
@override
Widget build(BuildContext context) {
return StreamBuilder(
stream: _isLoading,
builder: (context, snapshot) {
if (snapshot.hasData && snapshot.data) {
return LinearProgressIndicator();
}
else {
return Container();
}
}
);
}
}
是正确的,但我觉得 LinearProgressIndicator
比应该的厚一点。我的版本:
AppBar(
title: Text("Title"),
bottom: _AppBarProgressIndicator()
);
class:
const double _kAppBarProgressIndicatorHeight = 4.0;
class _AppBarProgressIndicator extends SizedBox implements PreferredSizeWidget {
AppBarProgressIndicator({Key key}) : super(
key: key,
height: _kAppBarProgressIndicatorHeight,
child: LinearProgressIndicator()
);
@override
Size get preferredSize => Size(
double.infinity,
_kAppBarProgressIndicatorHeight
);
}
有了就更好了:
AppBar(
title: Text("Title"),
bottom: _createProgressIndicator()
);
方法:
PreferredSize _createProgressIndicator() => PreferredSize(
preferredSize: Size(double.infinity, 4.0),
child: SizedBox(
height: 4.0,
child: LinearProgressIndicator()
)
);
这里有完整的例子,
这里线性进度条包含在appbar的总高度中
您可以在线测试。复制整个代码并将其粘贴到 dartpad:
https://dartpad.dartlang.org/flutter
import 'package:flutter/material.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
home: Scaffold(
body: Center(
child: HomePage(),
),
),
);
}
}
class HomePage extends StatefulWidget {
HomePage({Key key}) : super(key: key);
@override
_HomePageState createState() => _HomePageState();
}
class _HomePageState extends State<HomePage> {
bool contactingServer = true; // change this as needed and call setState afterwards
@override
Widget build(BuildContext context) {
return SafeArea(
child: Scaffold(
appBar: appBarWgt(),
body: Container(),
),
);
}
appBarWgt() {
double appBarHeight = 56;
double progressBarHeight = 5;
return PreferredSize(
preferredSize: Size.fromHeight(appBarHeight + progressBarHeight), // here the desired height
child: AppBar(
title: Text('Home'),
titleSpacing: 0,
centerTitle: true,
bottom: linearProgressBar(progressBarHeight),
),
);
}
linearProgressBar(_height) {
if (!contactingServer) {
return null;
}
return PreferredSize(
child: SizedBox(
width: double.infinity,
height: _height,
child: LinearProgressIndicator(),
),
preferredSize: const Size.fromHeight(0),
);
}
}
希望对您有所帮助,
谢谢
简单的方法
bottom: PreferredSize(
preferredSize: Size.fromHeight(6.0),
child: LinearProgressIndicator(backgroundColor: Colors.red.withOpacity(0.3),valueColor:new AlwaysStoppedAnimation<Color>(Colors.red),value: 0.25,),
),
我发现最简单的方法是:
- 使应用栏透明
- 为 Widget/Page
设置 extendBodyBehindAppBar: true
- 将线性指示器作为列或容器中的第一个小部件。
- 将您的内容包裹在安全区域中,然后砰的一声,它会将线性指示器推到应用栏下方。
您甚至可以为应用栏着色,并且仍然可以使用安全区域方法在下方显示指示器。我没试过。我只是偶然发现了这个。我已经发布了一个类似的问题,除了我希望我的问题出现在 AppBar 之上,所以我现在正在使用这种方法,到目前为止只成功地将指示器放置在 appbar 下方而不是上方。但是,如果我能弄清楚如何始终如一地为所有设备设置顶部间距,我可能会用这种方法获胜,这种方法似乎对应用栏上方和下方都有效。
如何在不使用应用栏底部 属性 且不增加应用栏高度的情况下将线性进度条放置在应用栏底部?
喜欢下图: Material design appbar
只需使用 LinearProgressIndicator()
作为 column
中的第一个小部件。然后你会在 Appbar
return Scaffold(
appbar: Appbar(
title: Text('App Bar'),),
body: Column(
children: <widget> [
linearProgressIndicator(),
Text('Hi'),]
),
)
为什么不想用底部属性?这就是 Flutter AppBar
小部件提供的用于在其中添加内容的钩子。否则,您必须创建自己的 AppBar
.
如果它对你有用,我创建了下面的代码片段,你可以像这样在你的应用栏中使用它。
appBar: new AppBar(
title: new Text("Title"),
backgroundColor: Colors.orange,
bottom: MyLinearProgressIndicator(
backgroundColor: Colors.orange,
),
),
MyLinearProgressIndicator
必须实施 preferredSize
getter。这就是为什么您需要创建自己的版本。
// Cant't use _kLinearProgressIndicatorHeight 'cause it is private in the
// progress_indicator.dart file
const double _kMyLinearProgressIndicatorHeight = 6.0;
class MyLinearProgressIndicator extends LinearProgressIndicator
implements PreferredSizeWidget {
MyLinearProgressIndicator({
Key key,
double value,
Color backgroundColor,
Animation<Color> valueColor,
}) : super(
key: key,
value: value,
backgroundColor: backgroundColor,
valueColor: valueColor,
) {
preferredSize = Size(double.infinity, _kMyLinearProgressIndicatorHeight);
}
@override
Size preferredSize;
}
这是结果:
@chemolins 的回答是完全有效的,但将小部件包装在 Preferred Size 小部件中可能更容易。该小部件采用 child
和类型 Size
的 preferredSize
这是我正在处理的应用程序的示例,包装了 StreamBuilder:
return Scaffold(
appBar: AppBar(
bottom: PreferredSize(
preferredSize: Size(double.infinity, 1.0),
child: ProgressBar(widget.bloc.isLoading),
),
---snip---
class ProgressBar extends StatelessWidget {
final Stream<bool> _isLoading;
ProgressBar(this._isLoading);
@override
Widget build(BuildContext context) {
return StreamBuilder(
stream: _isLoading,
builder: (context, snapshot) {
if (snapshot.hasData && snapshot.data) {
return LinearProgressIndicator();
}
else {
return Container();
}
}
);
}
}
LinearProgressIndicator
比应该的厚一点。我的版本:
AppBar(
title: Text("Title"),
bottom: _AppBarProgressIndicator()
);
class:
const double _kAppBarProgressIndicatorHeight = 4.0;
class _AppBarProgressIndicator extends SizedBox implements PreferredSizeWidget {
AppBarProgressIndicator({Key key}) : super(
key: key,
height: _kAppBarProgressIndicatorHeight,
child: LinearProgressIndicator()
);
@override
Size get preferredSize => Size(
double.infinity,
_kAppBarProgressIndicatorHeight
);
}
有了
AppBar(
title: Text("Title"),
bottom: _createProgressIndicator()
);
方法:
PreferredSize _createProgressIndicator() => PreferredSize(
preferredSize: Size(double.infinity, 4.0),
child: SizedBox(
height: 4.0,
child: LinearProgressIndicator()
)
);
这里有完整的例子,
这里线性进度条包含在appbar的总高度中
您可以在线测试。复制整个代码并将其粘贴到 dartpad:
https://dartpad.dartlang.org/flutter
import 'package:flutter/material.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
home: Scaffold(
body: Center(
child: HomePage(),
),
),
);
}
}
class HomePage extends StatefulWidget {
HomePage({Key key}) : super(key: key);
@override
_HomePageState createState() => _HomePageState();
}
class _HomePageState extends State<HomePage> {
bool contactingServer = true; // change this as needed and call setState afterwards
@override
Widget build(BuildContext context) {
return SafeArea(
child: Scaffold(
appBar: appBarWgt(),
body: Container(),
),
);
}
appBarWgt() {
double appBarHeight = 56;
double progressBarHeight = 5;
return PreferredSize(
preferredSize: Size.fromHeight(appBarHeight + progressBarHeight), // here the desired height
child: AppBar(
title: Text('Home'),
titleSpacing: 0,
centerTitle: true,
bottom: linearProgressBar(progressBarHeight),
),
);
}
linearProgressBar(_height) {
if (!contactingServer) {
return null;
}
return PreferredSize(
child: SizedBox(
width: double.infinity,
height: _height,
child: LinearProgressIndicator(),
),
preferredSize: const Size.fromHeight(0),
);
}
}
希望对您有所帮助,
谢谢
简单的方法
bottom: PreferredSize(
preferredSize: Size.fromHeight(6.0),
child: LinearProgressIndicator(backgroundColor: Colors.red.withOpacity(0.3),valueColor:new AlwaysStoppedAnimation<Color>(Colors.red),value: 0.25,),
),
我发现最简单的方法是:
- 使应用栏透明
- 为 Widget/Page 设置 extendBodyBehindAppBar: true
- 将线性指示器作为列或容器中的第一个小部件。
- 将您的内容包裹在安全区域中,然后砰的一声,它会将线性指示器推到应用栏下方。
您甚至可以为应用栏着色,并且仍然可以使用安全区域方法在下方显示指示器。我没试过。我只是偶然发现了这个。我已经发布了一个类似的问题,除了我希望我的问题出现在 AppBar 之上,所以我现在正在使用这种方法,到目前为止只成功地将指示器放置在 appbar 下方而不是上方。但是,如果我能弄清楚如何始终如一地为所有设备设置顶部间距,我可能会用这种方法获胜,这种方法似乎对应用栏上方和下方都有效。