简体   繁体   English

无状态小部件中具有初始偏移量的Flutter Listview

[英]Flutter Listview in stateless widget with initial offset

I have my own StatelessWidget with a ListView. 我有自己的带ListView的StatelessWidget。 I want it's state to be managed by parent StatefulWidget. 我希望它的状态由父StatefulWidget管理。

The behaviour I desire is that if I change a value, listView scrolls (or even jumps - it doesn't matter) to that value. 我想要的行为是,如果我更改一个值,listView会滚动(甚至跳转-没关系)到该值。

I thought that if I create stateless widget every time parent's setState() method is being invoked, the scrollController with initialOffset would make the list "move" but it doesn't. 我认为,如果每次调用父级的setState()方法时都创建无状态小部件,则带有initialOffset的scrollController会使列表“移动”,但事实并非如此。 What is worth mentioning is that on first build initialOffset works as it should. 值得一提的是,在首次构建时,initialOffset可以正常工作。

Here is example code of my problem: 这是我的问题的示例代码:

import 'package:flutter/material.dart';

void main() {
  runApp(new MyApp());
}

class MyApp extends StatelessWidget {
  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return new MaterialApp(
      title: 'Flutter Demo',
      theme: new ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: new MyHomePage(title: 'Flutter Demo Home Page'),
    );
  }
}

class MyHomePage extends StatefulWidget {
  MyHomePage({Key key, this.title}) : super(key: key);
  final String title;

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

class _MyHomePageState extends State<MyHomePage> {
  int _counter = 5;

  void _incrementCounter() {
    setState(() {
      _counter++;
    });
  }

  @override
  Widget build(BuildContext context) {
    return new Scaffold(
      appBar: new AppBar(
        title: new Text(widget.title),
      ),
      body: new MyClass(_counter),
      floatingActionButton: new FloatingActionButton(
        onPressed: _incrementCounter,
        child: new Icon(Icons.add),
      ),
    );
  }
}

class MyClass extends StatelessWidget {
  final int extraValue;
  final ScrollController scrollController;

  MyClass(this.extraValue):
  scrollController = new ScrollController(initialScrollOffset: extraValue*50.0);

  @override
  Widget build(BuildContext context) {
    return new ListView.builder(
        itemExtent: 50.0,
        itemCount: 100,
        controller: scrollController,
        itemBuilder: (BuildContext context, int index) {
      if (index != extraValue)
        return new Text(index.toString());
      else
        return new Text("EXTRA" + index.toString());
    });
  }
}

I'm not sure if it's a bug or my mistake. 我不确定这是错误还是错误。

Any ideas might be helpful :) 任何想法可能会有所帮助:)

EDIT : Inspired by Ian Hickson's answer I have solution to my problem: 编辑 :受伊恩·希克森(Ian Hickson)的回答启发,我已经解决了我的问题:

void _incrementCounter() {
    setState(() {
      _counter++;
      myClass.scrollController.animateTo(_counter*50.0, duration: new Duration(seconds: 1), curve: new ElasticOutCurve());
    });
  }

The initial offset is... the initial offset. 初始偏移量是... 初始偏移量。 Not the current offset. 不是当前的偏移量。 :-) :-)

You can cause the offset to change by calling methods on the ScrollController, like animateTo. 您可以通过调用ScrollController上的方法(例如animateTo)来使偏移量发生变化。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM