Flutter listview中嵌套橫向滾動的SingleChildScrollView保存滾動位置

【效果圖後續補上】緩存

結構是listview包含多種不一樣類型的item,而後其中一個是SingleChildScrollView。
點擊SingleChildScrollView中的item刷新listview中的部分數據。
可是發現當SingleChildScrollView滑動很遠以後,再滑動listview,當SingleChildScrollView滑出屏幕以後,再滑回來SingleChildScrollView就回到了初始位子,這確定不行啊。
listview的item滑出屏幕以後會被回收的,設斷點查看,來回滑動這個SingleChildScrollView並無從新建立,可是他裏面的內容會被從新建立,這樣每次從屏幕外面劃回來SingleChildScrollView就回到初始狀態了。markdown

接下來就是研究怎麼不讓它回收 重建,而後一頓查listview怎麼緩存,SingleChildScrollView怎麼保存滑動距離,保存狀態等,查看源碼發現SingleChildScrollView的controller默認是保存滑動距離的;可是由於SingleChildScrollView裏面的內容都從新建立了因此滑動距離也就無用了;ide

無心中發現listview有 addAutomaticKeepAlives 這麼一個屬性,可是直接設置成 true又很差使,後來查了下發現它須要接收到須要保存狀態的通知纔會去保存item的,
查了下用法,在 StatefulWidget 的 state 中重寫 wantKeepAlive,個人 SingleChildScrollView 裏面的item正好都是 StatefulWidget;oop

最終參考 這個文章 修改了下 SingleChildScrollView 裏面item的代碼;ui

class TextWidget extends StatefulWidget {
  final Key key;
  final String text;
  final bool selected;

  // 接收一個Key
  TextWidget(this.key, this.text, this.selected);

  @override
  State<StatefulWidget> createState() => TextWidgetState(this.text, this.selected);
}

class TextWidgetState extends State<TextWidget> with AutomaticKeepAliveClientMixin {
  String _text = "0";
  bool _selected = false;

  TextWidgetState(this._text, this._selected);

  @override
  Widget build(BuildContext context) {
    super.build(context);
    return Text(
      _text,
      textAlign: TextAlign.center,
      style: TextStyle(
          fontSize: _selected ? 18 : 16,
          fontWeight: _selected ? FontWeight.bold : FontWeight.normal,
          color: _selected ? color333 : color777),
    );
  }

  void onPressed(bool selected) {
    setState(() => _selected = selected);
  }

  @override
  bool get wantKeepAlive => true;
}
複製代碼

重要的是 with AutomaticKeepAliveClientMixin@override bool get wantKeepAlive => true;this

相關文章
相關標籤/搜索