如何让这个官方 Flutter ListView 示例在 iOS 上滚动?

问题描述 投票:0回答:1

我想在 Flutter 应用程序中创建一个可滚动的 ListView。我尝试从本教程复制使用 ListView 的示例代码。我修改了项目列表,使其比屏幕长。使用教程中的嵌入式版本时,它可以在浏览器中滚动,但当我构建 iOS 应用程序(使用 Visual Studio Code)并在 iOS 模拟器中测试它时,它不会滚动。

这是我修改后的代码:

import 'package:flutter/material.dart';

class Product {
  const Product({required this.name});

  final String name;
}

typedef CartChangedCallback = Function(Product product, bool inCart);

class ShoppingListItem extends StatelessWidget {
  ShoppingListItem({
    required this.product,
    required this.inCart,
    required this.onCartChanged,
  }) : super(key: ObjectKey(product));

  final Product product;
  final bool inCart;
  final CartChangedCallback onCartChanged;

  Color _getColor(BuildContext context) {
    // The theme depends on the BuildContext because different
    // parts of the tree can have different themes.
    // The BuildContext indicates where the build is
    // taking place and therefore which theme to use.

    return inCart //
        ? Colors.black54
        : Theme.of(context).primaryColor;
  }

  TextStyle? _getTextStyle(BuildContext context) {
    if (!inCart) return null;

    return const TextStyle(
      color: Colors.black54,
      decoration: TextDecoration.lineThrough,
    );
  }

  @override
  Widget build(BuildContext context) {
    return ListTile(
      onTap: () {
        onCartChanged(product, inCart);
      },
      leading: CircleAvatar(
        backgroundColor: _getColor(context),
        child: Text(product.name[0]),
      ),
      title: Text(
        product.name,
        style: _getTextStyle(context),
      ),
    );
  }
}

class ShoppingList extends StatefulWidget {
  const ShoppingList({required this.products, super.key});

  final List<Product> products;

  // The framework calls createState the first time
  // a widget appears at a given location in the tree.
  // If the parent rebuilds and uses the same type of
  // widget (with the same key), the framework re-uses
  // the State object instead of creating a new State object.

  @override
  State<ShoppingList> createState() => _ShoppingListState();
}

class _ShoppingListState extends State<ShoppingList> {
  final _shoppingCart = <Product>{};

  void _handleCartChanged(Product product, bool inCart) {
    setState(() {
      // When a user changes what's in the cart, you need
      // to change _shoppingCart inside a setState call to
      // trigger a rebuild.
      // The framework then calls build, below,
      // which updates the visual appearance of the app.

      if (!inCart) {
        _shoppingCart.add(product);
      } else {
        _shoppingCart.remove(product);
      }
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('Shopping List'),
      ),
      body: ListView(
        padding: const EdgeInsets.symmetric(vertical: 8),
        children: widget.products.map((product) {
          return ShoppingListItem(
            product: product,
            inCart: _shoppingCart.contains(product),
            onCartChanged: _handleCartChanged,
          );
        }).toList(),
      ),
    );
  }
}

void main() {
  runApp(const MaterialApp(
    title: 'Shopping App',
    home: ShoppingList(
      products: [
        Product(name: 'Eggs'),
        Product(name: 'Flour'),
        Product(name: 'Chocolate chips'),
        Product(name: 'Chocolate chips'),
        Product(name: 'Chocolate chips'),
        Product(name: 'Chocolate chips'),
        Product(name: 'Chocolate chips'),
        Product(name: 'Chocolate chips'),
        Product(name: 'Chocolate chips'),
        Product(name: 'Chocolate chips'),
        Product(name: 'Chocolate chips'),
        Product(name: 'Chocolate chips'),
        Product(name: 'Chocolate chips'),
        Product(name: 'Chocolate chips'),
        Product(name: 'Chocolate chips'),
      ],
    ),
  ));
}

ios flutter dart listview scroll
1个回答
0
投票

您的实际问题不是滚动问题,因为那会工作得很好。

您的问题应该在控制台中可见:

'package:flutter/src/rendering/sliver_multi_box_adaptor.dart': Failed assertion: line 259 pos 16: 'child == null || indexOf(child) > index': is not true.

这是因为您在材质应用程序中将

ObjectKey(product)
(这非常好)与
const
构造函数一起使用:

runApp(const MaterialApp(

这样,所有列表项也将被构造为 const。由于您的购物车中有多次相同的产品 (

Chocolate chips
),因此您多次生成完全相同的对象密钥,因此会出现错误。请参阅 this 答案,了解 const 在 Flutter 中如何工作的更多信息。

所以,要解决你可以做两件事:

  1. 删除
    const
    ,这样每个产品都会有自己的身份。
  2. 为了进行测试,请确保您的卡中有不同的项目。
© www.soinside.com 2019 - 2024. All rights reserved.