Flutter自定义AppBar和bottomNavigationBar

时间:2019-03-08 23:20:20

标签: dart flutter

有人可以帮助我实现自定义的Header(AppBar)和footer(bottomNavigationBar)。标题高度最小调整为20到最大50,页脚固定(显示/隐藏)根据用户滚动。在大多数情况下,标头应非常类似于AppBar / SliverAppbar。

自定义页眉/页脚的原因是我需要在AppBar和bottomNavigationBar上绘制小部件形状。而且使用默认的AppBar / bottomNavigationBar无法自定义索引,因此无论我体内的任何小部件形状都始终留在后面。

这是我正在处理的代码,似乎有点可以接受,您能帮我改进吗?

import 'package:flutter/material.dart';

class CustomScrollOne extends StatefulWidget {
  @override
  CustomScrollOneState createState() => new CustomScrollOneState();
}

class CustomScrollOneState extends State<CustomScrollOne> with SingleTickerProviderStateMixin{
  GlobalKey<ScaffoldState> scaffoldKey = GlobalKey<ScaffoldState>();
  ScrollController scrollController;
  double scrollOffset = 0.0;
  double scrollOffsetLast = 0.0;
  double upperSize = 50.0;

  @override
  initState() {
    scrollController = new ScrollController();
    scrollController.addListener(updateOffset);
    super.initState();
  }

  @override
  dispose() {
    scrollController.removeListener(updateOffset);
    scrollController.dispose();
    super.dispose();
  }

  void updateOffset() {
    setState(() {
      scrollOffset = scrollController.offset;
    });
  }

  scrollNotificationListener(ScrollNotification scrollNotification) {
    if (scrollNotification is ScrollUpdateNotification) {
      double minTop = 20.0;
      double maxTop = 50.0;

      if (scrollNotification.scrollDelta < 0) {
        // NOTE forward to normal
        if (upperSize < maxTop) {
           double activePosition = scrollOffsetLast + upperSize - scrollOffset;
          upperSize = (activePosition).clamp(upperSize, maxTop);
        }
      } else if (scrollNotification.scrollDelta > 0) {
        // NOTE reverse to large
        if (upperSize > minTop){
           double activePosition = scrollOffsetLast + upperSize - scrollOffset;
          upperSize = (activePosition).clamp(minTop, upperSize);
        }
      }
    } else if (scrollNotification is ScrollEndNotification) {
      scrollOffsetLast = scrollController.offset;
    }
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      key: scaffoldKey,
      backgroundColor: Colors.white,
      body: new SafeArea(
        child: Stack(
          alignment: AlignmentDirectional.topCenter,
          children: <Widget>[
            Positioned(
              top: upperSize,
              left: 14,
              right:14,
              bottom: 50,
              child: Container(
                color: Colors.grey[200],
                child: NotificationListener<ScrollNotification>(
                  onNotification: (e)=>scrollNotificationListener(e),
                  child: _listView(),
                )
              ),
            ),
            Positioned(
              top: 0,
              left: 50,
              right: 50,
              child: Container(
                width: 300,
                height: upperSize,
                color: Colors.grey[100],
                child: Text(upperSize.toString()),
              ),
            ),
            Positioned(
              top: 0,
              left: 1,
              bottom: 0,
              child: Container(
                width: 10,
                height: upperSize,
                color: Colors.red
              )
            )
          ]
        )
      )
    );
  }

  Widget _listView() {
    return new ListView.builder(
      itemCount: 60,
      itemBuilder: _listViewItem,
      controller: scrollController
    );
  }

  Widget _listViewItem(BuildContext context, int index) {
    return new Container(
      padding: EdgeInsets.all(10),
      margin: EdgeInsets.all(10),
      decoration: BoxDecoration(
        color: Colors.grey[50],
        // border: Border.all(width:0.2,color: Colors.grey)
      ),
      child: new Text('Item $index')
    );
  }
}

0 个答案:

没有答案