You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Flutter:调整字体大小时保持滚动位置且不固定容器高度

Flutter问题:调整字体大小后滚动位置重置的解决办法

代码示例

Padding(
        padding: const EdgeInsets.all(8.0),
        child: Column(
                      children: [
                            SizedBox(
                              width: 350,
                              // height: MediaQuery.of(context).size.height/7,

                              child: Container(
                                decoration: const BoxDecoration(
                                  color: Colors.white,

                                  borderRadius: BorderRadius.all(Radius.circular(23)),
                                ),

                                child:    Column(

                                  children: [

                                    const Text(""),

                                    Padding(
                                      padding: const EdgeInsets.all(15.0),

                                      child: Center(
                                        child: Text(
                                          "CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC"
                                          ,style: TextStyle(fontSize: getFontSize()),
                                          textAlign: TextAlign.center,

                                          // maxLines: 10,


                                        ),
                                      ),


                                    ),

                                    const Text(""),


                                    Row(
                                      mainAxisAlignment: MainAxisAlignment.center,
                                      children: [

                                        Expanded(
                                          child: SizedBox(

                                            height: 100,
                                            width: 200,

                                            child: Padding(
                                              padding: const EdgeInsets.all(20.0),
                                              child: Card(
                                                color: Colors.redAccent,
                                                elevation: 10,

                                                child: ListTile(
                                                  onTap: () {
                                                    //مشاركه للذكر
                                                  },

                                                  leading: const Icon(Icons.share),
                                                  iconColor: Colors.white,
                                                  title:  const Center(
                                                    child: FittedBox(
                                                      child: Text(
                                                        "C",
                                                        style: TextStyle(
                                                            color: Colors.white,
                                                            fontSize: 30,
                                                            fontFamily: 'mess'),
                                                      ),

                                                    ),
                                                  ),
                                                ),
                                              ),
                                            ),
                                          ),
                                        ),
                                        Expanded(
                                          child: SizedBox(

                                            height: 100,
                                            width: 200,

                                            child: Padding(
                                              padding: const EdgeInsets.all(20.0),
                                              child: Card(
                                                color: Colors.orangeAccent,
                                                elevation: 10,

                                                child: ListTile(
                                                  onTap: () {
                                                    if(mins>0) {

                                                      _incrementCounter();

                                                      //الاخفاء هنا
                                                      //return   ;


                                                    }else{




                                                    }



                                                  },

                                                  leading: const Icon(Icons.sunny_snowing),
                                                  iconColor: Colors.white,
                                                  title:  Center(
                                                    child: FittedBox(
                                                      child: Text(
                                                        '$mins g ',
                                                        style: const TextStyle(
                                                            color: Colors.white,
                                                            fontSize: 30,
                                                            fontFamily: 'mess'),
                                                      ),

                                                    ),
                                                  ),
                                                ),
                                              ),
                                            ),
                                          ),
                                        ),
                                      ],
                                    ),



                                  ],

                                ),

                              ),

                            ),
                          ],
                        ),
                      ),

问题描述

我使用了指定宽度但未设置高度的SizedBox,目的是让用户放大文本时容器可自动向下扩展。但当前代码存在问题:用户滚动阅读后调整字体大小,滚动位置会回到顶部,我希望滚动位置能保持不变。

解决方法

核心思路是通过ScrollController记录滚动偏移,在字体大小更新后恢复原位置,具体步骤如下:

1. 初始化控制器与偏移变量

在你的State类中定义滚动控制器和用于保存偏移的变量:

ScrollController _scrollController = ScrollController();
double _lastScrollOffset = 0.0;

2. 修改字体大小前记录偏移

在触发字体大小变化的逻辑里,先保存当前滚动位置:

// 示例:假设这是你调整字体大小的方法
void adjustFontSize() {
  // 记录当前滚动偏移
  if (_scrollController.hasClients) {
    _lastScrollOffset = _scrollController.offset;
  }
  // 更新字体大小的逻辑
  setState(() {
    // 这里修改控制字体大小的变量,比如你用到的getFontSize()依赖的状态
  });
}

3. 重绘后恢复滚动位置

重写didUpdateWidget方法,在Widget更新后的下一帧恢复滚动位置:

@override
void didUpdateWidget(covariant YourWidget oldWidget) {
  super.didUpdateWidget(oldWidget);
  WidgetsBinding.instance.addPostFrameCallback((_) {
    if (_scrollController.hasClients) {
      _scrollController.jumpTo(_lastScrollOffset);
    }
  });
}

4. 给滚动容器绑定控制器

把原来的外层Column包裹在SingleChildScrollView中,并绑定控制器:

SingleChildScrollView(
  controller: _scrollController,
  child: Padding(
    padding: const EdgeInsets.all(8.0),
    child: Column(
      children: [
        // 原来的SizedBox等内容
      ],
    ),
  ),
)

原理说明

字体大小变化会触发Widget重绘,滚动容器的尺寸改变后默认会回到初始位置。通过手动保存并恢复滚动偏移,就能让页面保持在用户之前阅读的位置。

内容的提问来源于stack exchange,提问作者Abu Abdullah

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.01 18:02:06