首页 > 解决方案 > 如何知道列表何时长到可以滚动?

问题描述

下面的屏幕截图包含两个产品列表,一个太短而无法滚动,另一个太长而无法滚动。

在此处输入图像描述

为了这个问题,为了更清楚,下面是带有更多可见颜色的屏幕截图:

在此处输入图像描述

为了向用户表明该列表是可滚动的,我将列表与位于列表末尾的渐变堆叠在一起。

我希望这个渐变只在列表足够长可以滚动时出现,但我无法找到区分可滚动和不可滚动列表的方法。

下面是具有底层列表和渐变的堆栈的代码:

Stack(
  children: <Widget>[
    ListView(
      scrollDirection: Axis.horizontal,
      children: <Widget>[
        //children go here
      ],
    ),
    Align(
      alignment: Alignment.centerRight,
      child: Container(
        width: 24,
        height: 24,
        decoration: BoxDecoration(
          gradient: LinearGradient(
            begin: FractionalOffset.centerRight,
            end: FractionalOffset.centerLeft,
            colors: [
              Colors.green,
              Colors.yellow
            ],
            stops: [
              0.0,
              1.0
            ]))),
    ),
  ],
),

标签: flutterflutter-layout

解决方案


我为您的要求做了一个简单的案例。首先构建列表并计算所有项目的宽度总和,
如果所有项目的宽度都超过 Listview 容器的宽度,
则重绘显示指示器,它可以滚动。

修改的

我更改为获取宽度动态 ListView 宽度。
您可以使用更改“listItemLength”值进行测试。

import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      debugShowCheckedModeBanner: false,
      title: "App",
      theme: new ThemeData(primarySwatch: Colors.amber),
      home: Test(),
    );
  }
}

class Test extends StatefulWidget {
  @override
  _TestState createState() => _TestState();
}

class _TestState extends State<Test> {
  List<GlobalKey> _globalKeys = [];
  GlobalKey _listviewGLobalKey = GlobalKey();
  double listTotalWidth = 0.0;
  double listviewWidth = 0.0;
  int listItemLength = 14;

  @override
  void initState() {
    super.initState();
    for (var i = 0; i < listItemLength; i++) {
      _globalKeys.add(GlobalKey());
    }

    WidgetsBinding.instance.addPostFrameCallback((_) => _getSizes());
  }

  _getSizes() {
    // Get a total Items width
    listTotalWidth = 0.0;
    _globalKeys.forEach((key) {
      final RenderBox renderBoxRed = key.currentContext.findRenderObject();
      final containerSize = renderBoxRed.size;
      listTotalWidth += containerSize.width;
    });
    print('total items width sum: $listTotalWidth');

    // Get a ListView's width
    final RenderBox listviewRenderBoxRed =
        _listviewGLobalKey.currentContext.findRenderObject();
    final listviewContainerSize = listviewRenderBoxRed.size;
    listviewWidth = listviewContainerSize.width;
    print('ListView width: $listviewWidth');

    setState(() {});
  }

  @override
  Widget build(BuildContext context) {
    // print('**** ${_scrollController.position.maxScrollExtent}');
    //  WidgetsBinding.instance
    //           .addPostFrameCallback((_) => _getSizes());
    return MaterialApp(
      debugShowCheckedModeBanner: false,
      title: "Title",
      theme: new ThemeData(primarySwatch: Colors.amber),
      home: Scaffold(
        body: SafeArea(
          child: Container(
            child: Row(
              children: <Widget>[
                Expanded(
                  child: ListView.builder(
                    key: _listviewGLobalKey,
                    scrollDirection: Axis.horizontal,
                    itemCount: listItemLength,
                    itemBuilder: (context, index) {
                      return Container(
                          key: _globalKeys[index],
                          padding: EdgeInsets.symmetric(horizontal: 5),
                          child: Center(
                              child: Text(
                            'aaa$index',
                          )));
                    },
                  ),
                ),
                if (listTotalWidth > listviewWidth) Icon(Icons.add),
              ],
            ),
          ),
        ),
      ),
    );
  }
}


推荐阅读