首页 > 解决方案 > 使用 jumpto 和 sticky_headers 包会导致 UI 问题

问题描述

我创建了一个新的颤振项目并添加了sticky_headers包。

之后我实现了一个具有 ScrollController 的列表生成器。我以 5 秒的间隔调用 setState 3 次,并修改将在构建方法上使用的全局偏移变量,以将列表跳转到新的偏移量(使用 SchedulerBinding.instance.addPostFrameCallback)。

问题是,在我调用 jumpto 方法后,标题被弄乱了(如果我手动滚动标题将回到正常位置)。

例子:

ezgif com-video-to-gif (1)

编码:

import 'package:flutter/material.dart';
import 'package:flutter/scheduler.dart';
import 'package:sticky_headers/sticky_headers.dart';

double offset = 0;

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: MyHomePage(),
    );
  }
}

class MyHomePage extends StatefulWidget {
  MyHomePage({Key key}) : super(key: key);

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

class _MyHomePageState extends State<MyHomePage> {

  ScrollController _scrollController = ScrollController();

  @override
  void initState() {
    super.initState();
    Future.delayed(Duration(seconds: 5)).then((_) => setState(() {
      offset = 3000;
    })).then((_) async => await Future.delayed(Duration(seconds: 5))).then((_) => setState(() {
      offset = 1000;
    })).then((_) async => await Future.delayed(Duration(seconds: 5))).then((_) => setState(() {
      offset = 5000;
    }));
  }

  @override
  Widget build(BuildContext context) {
    SchedulerBinding.instance.addPostFrameCallback((_) {
      print(offset);
      _scrollController.jumpTo(offset);
    });
    return Scaffold(body: Container(padding: EdgeInsets.only(top: 20),child: _buildList(context)));
  }

  Widget _buildList(BuildContext context) {
    return NotificationListener<ScrollNotification>(
        child: ListView.builder(
            controller: _scrollController,
            itemCount: 100,
            itemBuilder: (BuildContext context, int sectionIndex) => StickyHeader(
                header: Container(
                    height: 50,
                    alignment: Alignment.center,
                    color: Colors.blue,
                    child: Text("$sectionIndex")),

                content: ListView.builder(
                    itemCount: 10,
                    shrinkWrap: true,
                    physics: NeverScrollableScrollPhysics(),
                    itemBuilder: (context, rowIndex) => Container(
                        color: Colors.white,
                        child: Text("$sectionIndex"))))),

        onNotification: (ScrollNotification scrollNotification) {
          offset = _scrollController.offset;
          print(offset);
          return true;
        });
  }
}

标签: flutterdart

解决方案


推荐阅读