簡體   English   中英

如何使用 Flutter 中的 StatelessWidget 和提供程序以編程方式滾動 ListView?

[英]How to scroll a ListView programmatically with StatelessWidget and provider in Flutter?

根據很多 Flutter provider 教程,建議使用 StatelessWidget 而不是 StatefulWidget with provider。 但是在使用 StatelessWidget 時我找不到滾動 ListView 的方法。

假設我們有一個包含多行文本的 ListView,可以動態附加,並且應該始終滾動到中間行。 像這樣:

import 'package:flutter/material.dart';
import 'package:provider/provider.dart';

class MyData with ChangeNotifier {
  List<String> _lines = [];
  MyData() {
    for (int i = 0; i < 100; i++) {
      _lines.add("line $i");
    }
  }

  List<String> get lines => _lines;
  void add(line) {
    _lines.add(line);
    notifyListeners();
  }
}

void main() {
  MyData data = new MyData();
  final app = ChangeNotifierProvider<MyData>.value(value: data, child: MyApp());
  runApp(app);
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData.dark(),
      home: MyHomePage(),
    );
  }
}

class DataPage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    final _data = Provider.of<MyData>(context);
    return Scaffold(
        appBar: AppBar(),
        body: ListView.builder(
            itemCount: _data.lines.length,
            itemBuilder: (context, index) {
              return Text(_data.lines[index]);
            }));
  }
}

class MyHomePage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    final _data = Provider.of<MyData>(context);
    return Scaffold(
        appBar: AppBar(
          actions: <Widget>[
            IconButton(
                icon: Icon(Icons.add),
                onPressed: () {
                  _data.add("new line");
                })
          ],
        ),
        body: Center(child: Text("${_data.lines.length} lines")),
        floatingActionButton: FloatingActionButton(
          onPressed: () => Navigator.of(context)
              .push(MaterialPageRoute(builder: (context) => DataPage())),
          child: Icon(Icons.list),
        ));
  }
}

添加新行時,有什么方法可以保持滾動到 ListView 的中間?

使用 WidgetsBinding.instance,在構建小部件后調用 scrollTo。 每次 Provider MyData 發送通知時

我希望這對你沒問題,身高是一個要求

class DataPage extends StatelessWidget {

  final _controller = ScrollController();
  final _height = 30.0;

  @override
  Widget build(BuildContext context) {
    final _data = Provider.of<MyData>(context);

    scrollTo() {
      print(_data.lines.length);
      _controller.jumpTo(_data.lines.length / 4 * _height);
    }

    WidgetsBinding.instance
        .addPostFrameCallback((_) => scrollTo());

    return Scaffold(
        appBar: AppBar(),
        body: ListView.builder(
          controller: _controller,
            itemCount: _data.lines.length,
            itemBuilder: (context, index) {
              return new Container(child: Text(_data.lines[index]), height: _height,);
            }));
  }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM