如何将线性进度条放置在appbar底部?

时间:2018-11-27 04:12:59

标签: flutter flutter-layout

如何在不使用appbar的bottom属性且不增加appbar高度的情况下将线性进度条放置在appbar底部?

如下图所示: Material design appbar

7 个答案:

答案 0 :(得分:2)

为什么不想使用bottom属性?这就是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;
}

这是结果:

enter image description here

答案 1 :(得分:1)

@chemamolins的答案是完全正确的,但是仅将您的小部件包装在Preferred Size小部件中可能会更容易。该小部件采用child类型的preferredSizeSize类型的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(); } } ); } } ,这是我正在处理的应用程序的一个示例,其中包装了StreamBuilder:

// Hash Maps
Map<String, String> nameEmailMap = new HashMap<String, String>();

答案 2 :(得分:0)

只需使用LinearProgressIndicator()作为column中的第一个小部件。然后,您将在Appbar

下获得进度栏
return Scaffold(
appbar: Appbar(
title: Text('App Bar'),),
body: Column(
children: <widget> [
linearProgressIndicator(),
Text('Hi'),]
),
)

答案 3 :(得分:0)

Chemamolins' answer是正确的,但是我觉得LinearProgressIndicator比应该的要厚一些。我的版本:

AppBar(
  title: Text("Title"),
  bottom: _AppBarProgressIndicator()
);

课程:

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
  );
}

有了Adil Sadik's otimization,情况会更好:

AppBar(
  title: Text("Title"),
  bottom: _createProgressIndicator()
);

方法:

PreferredSize _createProgressIndicator() => PreferredSize(
  preferredSize: Size(double.infinity, 4.0),
  child: SizedBox(
    height: 4.0,
    child: LinearProgressIndicator()
  )
);

答案 4 :(得分:0)

完整示例

线性进度条包含在应用栏的总高度中

您可以在线对其进行测试。复制整个代码并将其粘贴到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),
    );
  }
}

我希望这会有所帮助,

谢谢

答案 5 :(得分: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,),
),

答案 6 :(得分:-1)

我发现最简单的方法是:

  1. 使应用栏透明
  2. 为小部件/页面设置extendBodyBehindAppBar:true
  3. 将您的线性指示器作为列或容器中的第一个小部件。
  4. 将您的内容包裹在安全区域中,然后砰的一声,它会将线性指示器推到应用栏下方。

您甚至可以为应用栏着色,并且仍然使用安全区域方法让指示器显示在下方。我没有试过。我只是偶然发现了这一点。我已经发布了一个类似的问题,但我希望我的问题出现在 AppBar 的顶部,所以我现在正在使用这种方法,到目前为止,只能成功地将指标放置在 appbar 下方而不是上方。但是如果我能弄清楚如何为所有设备一致地设置顶部的间距,我可能会用这种方法获胜,这种方法似乎对应用栏的顶部和底部都有效。