Flutter滚动Listview隐藏显示容器

时间:2020-10-27 12:25:04

标签: flutter listview

我的屏幕具有固定高度的顶部容器A,固定顶部容器B和列表视图。 enter image description here enter image description here

我想做的是向下滚动Listview时将隐藏Container A并将Container B固定在顶部,如果向上滚动至Listview的开头,则向后显示Container A

我当前的代码能够在listview项很多(20)时实现此目的,而在listview项数更少时不起作用。

是实现这一目标的更好方法吗?

我的代码

import 'package:flutter/material.dart';

class TestPage extends StatefulWidget {
  static const String routeName = '/testScreen';
  @override
  _TestPageState createState() => _TestPageState();
}

class _TestPageState extends State<TestPage> {
  @override
  Widget build(BuildContext context) {
    double blockHeight = 225;
    double blockBHeight = 50;
    final ValueNotifier<double> notifier = ValueNotifier(0);
    final ValueNotifier<double> notifierCardListMarginTop =
        ValueNotifier(blockHeight + blockBHeight);
    return Scaffold(
        appBar: AppBar(
          title: Text('Test'),
        ),
        body: Stack(
          children: [
            Container(
              decoration: BoxDecoration(
                color: Color(0xFFF1EFF1),
              ),
            ),
            NotificationListener<ScrollNotification>(
              onNotification: (n) {
                print(n.metrics.pixels);
                if (n.metrics.pixels >= blockBHeight) {
                  notifier.value = -blockHeight;
                  notifierCardListMarginTop.value = blockBHeight;
                } else if (n.metrics.pixels <= 10) {
                  notifier.value = 0;
                  notifierCardListMarginTop.value = 275;
                }
                return false;
              },
              child: CardListListener(notifier: notifierCardListMarginTop),
            ),
            HideableWidget(height: blockHeight, notifier: notifier),
          ],
        ));
  }
}

class CardListListener extends StatelessWidget {
  final ValueNotifier<double> notifier;

  CardListListener({@required this.notifier});

  @override
  Widget build(BuildContext context) {
    return ValueListenableBuilder<double>(
      valueListenable: notifier,
      builder: (context, value, child) {
        return Container(
          // here get the keep changing value of margin top value
          margin: EdgeInsets.only(top: value),
          child: ListView.builder(
            itemCount: 6,
            itemBuilder: (context, index) {
              return Container(
                height: 80,
                padding: const EdgeInsets.all(16),
                alignment: Alignment.centerLeft,
                child: Text('Item $index'),
              );
            },
          ),
        );
      },
    );
  }
}

class HideableWidget extends StatelessWidget {
  final double height;
  final ValueNotifier<double> notifier;

  HideableWidget({@required this.height, @required this.notifier});

  @override
  Widget build(BuildContext context) {
    return ValueListenableBuilder<double>(
      valueListenable: notifier,
      builder: (context, value, child) {
        return Transform.translate(
          // value here is change based on the scroll
          offset: Offset(0, value),
          child: Container(
            // the top block total height
            height: 275,
            color: Color(0xFF035AA6),
            child: Column(
              children: [
                Container(
                  height: 225,
                  width: double.infinity,
                  child: Text('Container A'),
                ),
                Container(
                  color: Colors.red,
                  width: double.infinity,
                  height: 50,
                  child: Text('Container B'),
                ),
              ],
            ),
          ),
        );
      },
    );
  }
}

0 个答案:

没有答案
相关问题