Flutter ExpansionPanelList - 扩展回调不起作用

Posted

技术标签:

【中文标题】Flutter ExpansionPanelList - 扩展回调不起作用【英文标题】:Flutter ExpansionPanelList - expansionCallback not working 【发布时间】:2021-06-07 22:39:27 【问题描述】:

我正在通过使用Provider 包而不是使Widget 成为statefulWidget 来实现ExpansionPanelList。但是,expansionCallback 永远无法正常工作。如果我单击屏幕上的第一个折叠列表,它将永远不会展开。具体来说,data[0].isExpandedSummitView.dart 中始终是false。控制台没有报错。

这是我的SummitView.dart

import 'package:delta_y/modules/summits/model/Item.dart';
import 'package:delta_y/modules/summits/model/ItemsList.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';

class SummitView extends StatelessWidget 
  @override
  Widget build(BuildContext context) 
    return Scaffold(
        appBar: AppBar(
          title: Text("Summit/Milestone"),
        ),
        body: ChangeNotifierProvider(
          create: (context) => ItemsList(),
          child: Summit(),
        ));
  


class Summit extends StatelessWidget 
  @override
  Widget build(BuildContext context) 
    final itemModel = Provider.of<ItemsList>(context);
    // List<Item> _data = generateItems(8);
    itemModel.generateItems(8);

    return Stack(children: <Widget>[
      SingleChildScrollView(
        child: Container(
          child: ExpansionPanelList(
            expansionCallback: (int index, bool isExpanded) 
              itemModel.setExpanded(index, isExpanded);
              print("INDEX : $index ... $isExpanded");
            ,
            children: itemModel.data.map<ExpansionPanel>((Item item) 
              bool isData0Expanded = itemModel.data[0].isExpanded;
              print('**********');
              print(isData0Expanded);
              print('**********');

              return ExpansionPanel(
                headerBuilder: (BuildContext context, bool isExpanded) 
                  return ListTile(
                    title: Text(item.headerValue),
                  );
                ,
                body: ListTile(
                    title: Text(item.expandedValue),
                    subtitle:
                    Text('To delete this panel, tap the trash can icon'),
                    trailing: Icon(Icons.delete),
                    onTap: () 
                      itemModel.deleteItem(item);
                    ),
                isExpanded: item.isExpanded,
              );
            ).toList(),
          ),
        ),
      ),
      Align(
          alignment: Alignment.bottomCenter,
          child: FractionallySizedBox(
            child: ElevatedButton(
              style: ElevatedButton.styleFrom(
                primary: Colors.white,
                onPrimary: Colors.black,
              ),
              onPressed: () 
                Navigator.pop(context);
              ,
              child: Text('Create Summit'),
            ),
            widthFactor: 0.9,
          )),
    ]);
  

这是ItemsList.dart

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

class ItemsList extends ChangeNotifier
  List<Item> _data;

  List<Item> get data => _data;

  generateItems(int numberOfItems) 
    _data = List.generate(numberOfItems, (int index) 
      return Item(
        headerValue: 'Panel $index',
        expandedValue: 'This is item number $index',
      );
    );
  

  setExpanded(int index, bool isExpanded) 
    _data[index].isExpanded = !isExpanded;
    notifyListeners();
  

  deleteItem(Item item) 
    _data.removeWhere((currentItem) => item == currentItem);
    notifyListeners();
  

这是Item.dart

import 'package:flutter/material.dart';

class Item
  Item(
    @required this.expandedValue,
    @required this.headerValue,
    this.isExpanded = false,
  );

  String expandedValue;
  String headerValue;
  bool isExpanded;

【问题讨论】:

【参考方案1】:

问题是由这一行引起的:

class Summit extends StatelessWidget 
  @override
  Widget build(BuildContext context) 

    // ... other lines

    itemModel.generateItems(8); <---- 

在 build() 中调用方法时,每次屏幕收到来自Provider 的事件时都会调用该方法。在这种情况下,您的项目列表每次都会不断生成,这使得 isExpanded 始终为 false

要解决此问题,最好添加一些条件以防止重置项目列表,或者在创建ItemsList 时生成项目,例如:

body: ChangeNotifierProvider(
    create: (context) => ItemsList()..generateItems(8),
    child: Summit(),

结果:

【讨论】:

以上是关于Flutter ExpansionPanelList - 扩展回调不起作用的主要内容,如果未能解决你的问题,请参考以下文章

[Flutter] flutter项目一直卡在 Running Gradle task 'assembleDebug'...

flutter 日志输出,Flutter打印日志,flutter log,flutter 真机日志

Flutter开发 Flutter 包和插件 ( Flutter 包和插件简介 | 创建 Flutter 插件 | 创建 Dart 包 )

flutter与原生混编(iOS)

Flutter-布局

如何解决flutter gradle build error?C:\flutter\packages\flutter_tools\gradle\flutter.gradle' line: 991