0

在我目前正在进行的项目中,我有一个Scaffold包含SinlgeChildScrollView. 在此SingleChildScrollView显示实际内容,允许在内容离开屏幕时滚动。

虽然这对我大约 90% 的屏幕有意义,但是我有一个屏幕显示 2 ExpansionTiles。这两个都可能包含许多条目,扩展时它们会变得非常大。

现在的问题是,我希望ExpansionTile最迟在它到达屏幕底部时停止扩展并使ExpansionTile(即ListTiles)内的内容可滚动。

当前,当条目过多时,屏幕如下所示:

在此处输入图像描述

正如您可以清楚地看到的那样,ExpansionTile离开屏幕,迫使用户滚动实际屏幕,这将导致两者的标题ExpansionTiles从屏幕上消失,因为列表中有足够的条目。即使SingleChildScrollView从 Scaffold 中移除 也不能解决问题,只会导致RenderOverflow.

在此处输入图像描述

用于生成 Scaffold 及其内容的代码如下:

class MembershipScreen extends StatefulWidget {
  @override
  State<StatefulWidget> createState() => _MembershipScreenState();

}

class _MembershipScreenState extends State<MembershipScreen> {

  String _fontFamily = 'OpenSans';

  Widget _buildMyClubs() {
    return Container(
      decoration: BoxDecoration(
          color: Colors.white,
          border: Border.all(
              color: Color(0xFFD2D2D2),
              width: 2
          ),
          borderRadius: BorderRadius.circular(25)
      ),
      child: Theme(
        data: ThemeData().copyWith(dividerColor: Colors.transparent),
        child: ExpansionTile(
            title: Text("My Clubs"),
            trailing: Icon(Icons.add),
            children: getSearchResults(),
        ),
      )
    );
  }

  Widget _buildAllClubs() {
    return Container(
      decoration: BoxDecoration(
          color: Colors.white,
          border: Border.all(
              color: Color(0xFFD2D2D2),
              width: 2
          ),
          borderRadius: BorderRadius.circular(25)
      ),
      child: Theme(
        data: ThemeData().copyWith(dividerColor: Colors.transparent),
        child: SingleChildScrollView(
          child: ExpansionTile(
            title: Text("All Clubs"),
            trailing: Row(
              mainAxisSize: MainAxisSize.min,
              children: [
                Icon(Icons.add)
              ],
            ),
            children: getSearchResults(),
          ),
        )
      )
    );
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      extendBody: true,
      body: AnnotatedRegion<SystemUiOverlayStyle>(
          value: SystemUiOverlayStyle.light,
          child: GestureDetector(
            onTap: () => FocusScope.of(context).unfocus(),
            child: Stack(
              children: <Widget>[
                Container(
                  height: double.infinity,
                  width: double.infinity,
                  decoration: BoxDecoration(
                      gradient: kGradient //just some gradient
                  ),
                ),
                Center(
                  child: Container(
                  height: double.infinity,
                  constraints: BoxConstraints(maxWidth: 500),
                  child: SingleChildScrollView(
                      physics: AlwaysScrollableScrollPhysics(),
                      padding: EdgeInsets.symmetric(horizontal: 40.0, vertical: 20.0),
                      child: Column(
                        mainAxisAlignment: MainAxisAlignment.center,
                        children: <Widget>[
                          Text(
                            'Clubs',
                            style: TextStyle(
                                fontSize: 30.0,
                                color: Colors.white,
                                fontFamily: _fontFamily,
                                fontWeight: FontWeight.bold),
                          ),
                          SizedBox(
                            height: 20,
                          ),
                          _buildMyClubs(),
                          SizedBox(height: 20,),
                          _buildAllClubs()
                        ],
                      ),
                    ),
                  ),
                ),
              ],
            ),
          )
      ),
    );
  }

  List<Widget> getSearchResults() {
    return [
      ListTile(
        title: Text("Test1"),
        onTap: () => print("Test1"),
      ),
      ListTile(
        title: Text("Test2"),
        onTap: () => print("Test2"),
      ), //etc..
    ];
  }

}

我希望我没有通过删除不相关的部分来破坏代码,以便在将其发布到此处之前减小大小。希望有人知道如何实现我打算在这里做的事情,并且可以帮助我解决这个问题。

编辑

由于可能不容易理解我试图实现的目标,因此我尝试为所需的行为提出一个可视化:

在此处输入图像描述

因此,用虚线包围的项目包含在列表中,但无法显示,因为它们会超出视口的边界。因此ExpansionTile,包含该项目的内容需要为用户提供一个滚动条,以便在列表中向下滚动。因此,两者ExpansionTiles始终可见。

4

1 回答 1

0

试试下面的代码希望它对你有帮助。ExpansionTile()在里面添加你的小部件Column()Column()包裹起来SingleChildScrollView()

  1. 在此处参考 SingleChildScrollView
  2. 请参阅此处的
  3. 您也可以在此处参考我对 ExpansionPanel的回答
  4. 在此处参考列表
  5. 在此处参考 ListView.builder()

你的清单:

  List<Widget> getSearchResults = [
    ListTile(
      title: Text("Test1"),
      onTap: () => print("Test1"),
    ),
    ListTile(
      title: Text("Test2"),
      onTap: () => print("Test2"),
    ), //etc..
  ];

您的小部件使用ListView.builder()

SingleChildScrollView(
    padding: EdgeInsets.all(20),
    child: Column(
      children: [
        Card(
          child: ExpansionTile(
            title: Text(
              "My Clubs",
            ),
            trailing: Icon(
              Icons.add,
            ),
            children: [
              ListView.builder(
                shrinkWrap: true,
                itemBuilder: (BuildContext context, int index) {
                  return Column(
                    children: getSearchResults,
                  );
                },
                itemCount: getSearchResults.length, // try 50 length just testing
              ),
            ],
          ),
        ),
      ],
    ),
  ),

您的简单小部件:

 SingleChildScrollView(
    padding: EdgeInsets.all(20),
    child: Column(
      children: [
        Card(
          child: ExpansionTile(
            title: Text(
              "My Clubs",
            ),
            trailing: Icon(
              Icons.add,
            ),
            children:getSearchResults
             
          ),
        ),
      ],
    ),
  ),

您的结果屏幕 ->图片

于 2021-12-05T07:55:27.707 回答