如何创建使所需元素居中的列表视图

DAV*_*TEC 6 flutter flutter-layout flutter-animation

我正在做类似于这个视频的事情:https : //youtu.be/fpqHUp4Sag0

使用以下代码生成列表视图,但是当以这种方式使用控制器时,元素位于列表视图的顶部,我需要将其居中

Widget _buildLyric() {

  return ListView.builder(
    itemBuilder: (BuildContext context, int index) => _buildPhrase(lyric[index]),
    itemCount: lyric.length,
    itemExtent: 90.0,
    controller: _scrollController,
  );
}


void goToNext() {
  i += 1;
  if (i == lyric.length - 1) {
    setState(() {
      finishedSync = true;
    });
  }
  syncLyric.addPhrase(
      lyric[i], playerController.value.position.inMilliseconds);

  _scrollController.animateTo(i*90.0,
      curve: Curves.ease, duration: new Duration(milliseconds: 300));
}
Run Code Online (Sandbox Code Playgroud)

Pab*_*rra 6

使用centershrinkWrap: true

    Center(
        child: new ListView.builder(
                          shrinkWrap: true,
                          itemCount: list.length,
                          itemBuilder: (BuildContext context, int index) {
                            return Text("Centered item");
                          },
                        ),
  );
Run Code Online (Sandbox Code Playgroud)


rmt*_*zie 1

你必须做一些数学计算!(不,不是数学)

似乎您的 goToNext() 函数是在应用程序运行时调用的,而不是在构建期间调用的。这使它变得更容易 - 您可以简单地使用context.size. 否则你必须使用 LayoutBuilder 和 maxHeight。

然后,您可以将其分成两部分以获得一半,然后添加/减去您需要的任何内容,以使您的项目按照您想要的方式定位(因为您在示例中将其高度指定为 90,所以我假设您可以使用 45 来获得你要)。

这是一个可以粘贴到文件中运行的示例:

import 'dart:async';

import 'package:flutter/material.dart';

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

class Wid extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return new MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: Text("Scrolling by time"),
        ),
        body: new Column(
          children: <Widget>[
            Expanded(child: Container()),
            Container(
              height: 300.0,
              color: Colors.orange,
              child: ScrollsByTime(
                itemExtent: 90.0,
              ),
            ),
            Expanded(child: Container()),
          ],
        ),
      ),
    );
  }
}

class ScrollsByTime extends StatefulWidget {
  final double itemExtent;

  const ScrollsByTime({Key key, @required this.itemExtent}) : super(key: key);

  @override
  ScrollsByTimeState createState() {
    return new ScrollsByTimeState();
  }
}

class ScrollsByTimeState extends State<ScrollsByTime> {
  final ScrollController _scrollController = new ScrollController();

  @override
  void initState() {
    super.initState();
    Timer.periodic(Duration(seconds: 1), (timer) {
      _scrollController.animateTo(
        (widget.itemExtent * timer.tick) - context.size.height / 2.0 + widget.itemExtent / 2.0,
        duration: Duration(milliseconds: 300),
        curve: Curves.ease,
      );
    });
  }

  @override
  Widget build(BuildContext context) {
    return ListView.builder(
      itemBuilder: (context, index) {
        return Center(child: Text("Item $index"));
      },
      itemExtent: widget.itemExtent,
      controller: _scrollController,
    );
  }
}
Run Code Online (Sandbox Code Playgroud)