flutter 扩展面板 listView Builder

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

一个领域的初学者,我有这段代码可以工作,但是在单击的情况下出现错误 当我单击任何卡片时,所有卡片也会打开。我想打开一张我只需点击的卡片

import 'dart:io';
import 'package:english_club/data/im.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter/widgets.dart';


class Novals extends StatefulWidget {
  @override
  _NovalsState createState()
  {
    return _NovalsState();
  }
}

class _NovalsState extends State<Novals> {
  bool _expanded = false;
  var _test = "Full Screen";
  @override
  Widget build(BuildContext context) {
    return Scaffold(
       resizeToAvoidBottomInset: false,
      body: ListView.builder(
        itemCount: storys.length,

        itemBuilder: (context, index){
          return SingleChildScrollView(
            child: Column(
              children: [
                Center(
                  child: Container(
                    margin: EdgeInsets.all(10),
                    color: Colors.green,
                    child: ExpansionPanelList(
                    animationDuration: Duration(milliseconds: 2000),
                    children: [
                      ExpansionPanel(
                          headerBuilder: (context, isExpanded) {
                            return ListTile(
                              title: Text(storys[index]["name"], style: TextStyle(color: Colors.black),),
                            );
                          },
                          body:ListTile(
                            title: Text(storys[index]["lines"],style: TextStyle(color: Colors.black)),
                          ),
                        isExpanded: _expanded,
                        canTapOnHeader: true,
                      ),
                    ],
                    dividerColor: Colors.grey,
                    expansionCallback: (panelIndex, isExpanded) {
                      _expanded = !_expanded;
                      setState(() {

                      });
                    },

              ),
             ),
                ),
            ]
            ),
          );
        }
      ),
    );
  }
}

我试图解决这个问题,但我无法让代码显示故事的名称,当用户点击它时,整个故事就会出现

flutter listview expansion
3个回答
2
投票

首先,您应该删除

SingleChildScrollView
作为
ListView
子项。
ListView.builder
足以为您的
Scaffold
提供滚动功能。

对于主要问题,您应该将每个项目拆分为具有自己的

Widget
状态的单独
_expanded
。这将使您的 UI 更快,小部件将单独展开,并且整个屏幕无需在每个项目
setState()
后重新加载。

示例代码:

class Novals extends StatefulWidget {
  @override
  _NovalsState createState()
  {
    return _NovalsState();
  }
}

class _NovalsState extends State<Novals> {
  var _test = "Full Screen";
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      resizeToAvoidBottomInset: false,
      body: ListView.builder(
          itemCount: storys.length,
          itemBuilder: (context, index){
            return StoryWidget(story: storys[index]);
          }
      ),
    );
  }
}

class StoryWidget extends StatefulWidget {
  final Map<String, dynamic> story;
  const StoryWidget({Key? key, required this.story}) : super(key: key);

  @override
  _StoryWidgetState createState() => _StoryWidgetState();
}

class _StoryWidgetState extends State<StoryWidget> {  
bool _expanded = false;

@override
  Widget build(BuildContext context) {
    return Column(
        children: [
          Center(
            child: Container(
              margin: EdgeInsets.all(10),
              color: Colors.green,
              child: ExpansionPanelList(
                animationDuration: Duration(milliseconds: 2000),
                children: [
                  ExpansionPanel(
                    headerBuilder: (context, isExpanded) {
                      return ListTile(
                        title: Text(widget.story["name"], style: TextStyle(color: Colors.black),),
                      );
                    },
                    body:ListTile(
                      title: Text(widget.story["lines"],style: TextStyle(color: Colors.black)),
                    ),
                    isExpanded: _expanded,
                    canTapOnHeader: true,
                  ),
                ],
                dividerColor: Colors.grey,
                expansionCallback: (panelIndex, isExpanded) {
                  _expanded = !_expanded;
                  setState(() {});
                },
              ),
            ),
          ),
        ]
    );
  }
}

P/s:最好使用

story
将您的
jsonDecode()
放入模型类中,而不是直接使用
Map
。从长远来看,它将帮助您避免错误并更好地进行维护


0
投票

问题是您对

_expanded
中的项目使用相同的
ListView
变量。

class _NovalsState extends State<Novals> {
  bool _expanded = false;

  ...

  @override
  Widget build(BuildContext context) {
    ...
  }
}

因此,当您在

itemBuilder
中调用
ListView
时,它会对每个项目使用相同的
_expanded
值。

解决方案:

_expanded
变量从
State
移动到
itemBuilder
函数体内。

class _NovalsState extends State<Novals> {

  var _test = "Full Screen";

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      resizeToAvoidBottomInset: false,
      body: ListView.builder(
          itemCount: storys.length,
          itemBuilder: (context, index) {
            bool _expanded = false;
            return SingleChildScrollView(
              child: Column(children: [
                Center(
                  child: Container(
                    margin: EdgeInsets.all(10),
                    color: Colors.green,
                    child: ExpansionPanelList(
                      animationDuration: Duration(milliseconds: 2000),
                      children: [
                        ExpansionPanel(
                          headerBuilder: (context, isExpanded) {
                            return ListTile(
                              title: Text(
                                storys[index]["name"],
                                style: TextStyle(color: Colors.black),
                              ),
                            );
                          },
                          body: ListTile(
                            title: Text(storys[index]["lines"],
                                style: TextStyle(color: Colors.black)),
                          ),
                          isExpanded: _expanded,
                          canTapOnHeader: true,
                        ),
                      ],
                      dividerColor: Colors.grey,
                      expansionCallback: (panelIndex, isExpanded) {
                        _expanded = !_expanded;
                        setState(() {});
                      },
                    ),
                  ),
                ),
              ]),
            );
          }),
    );
  }
}

查看 Dart 的词法范围


0
投票

我在 ExpansionPanelList 中显示评论列表。列表中的每个注释都映射为扩展面板的注释类型。扩展面板使用 isExpanded 值来确定它是折叠还是展开。 ExpansionPanelList 回调扩展回调是在折叠或展开事件切换值时调用的。

 class Comment {
  final String title;
  final String body;
  bool isExpanded = false;

  Comment(this.title, this.body);
}
   ExpansionPanelList(
                        expansionCallback: (int index, bool isExpanded) {
                          setState(() {
                            _commentsList[index].isExpanded = !isExpanded;
                          });
                        },
                        children: _commentsList
                            .map<ExpansionPanel>((Comment comment) {
                          return ExpansionPanel(
                            headerBuilder:
                                (BuildContext context, bool isExpanded) {
                              return const ListTile(title: Text("Comments"));
                            },
                            body: Column(
                              children: [
                                Text(comment.body),
                              ],
                            ),
                            isExpanded: comment.isExpanded,
                          );
                        }).toList(),
                      )
© www.soinside.com 2019 - 2024. All rights reserved.