flutter 如果ScrollController已经在底部,则使其滚动到底部

7rfyedvj  于 2023-03-31  发布在  Flutter
关注(0)|答案(1)|浏览(355)

我有一个ListView.builder和一个scrollController

import 'dart:io';
import 'dart:math';

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

class StartProcessWidget extends HookWidget {
  final ScrollController scrollController = ScrollController();

  StartProcessWidget({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    var ouputs = useState<List<String>>([]);

    scrollDown() {
      if (scrollController.hasClients) {
        scrollController.jumpTo(scrollController.position.maxScrollExtent);
      }
    }

    String generateRandomString(int len) {
      var r = Random();
      return String.fromCharCodes(List.generate(len, (index) => r.nextInt(33) + 89));
    }

    addElements() {
      for (var i = 0; i < 1000; i++) {
        ouputs.value = [...ouputs.value, generateRandomString(Random().nextInt(100))];
        sleep(const Duration(milliseconds: 500));
      }
    }

    useEffect(() {
      addElements();
    }, []);

    useEffect(() {
      scrollDown();
    }, [ouputs.value]);

    return Container(
      height: 500,
      child: ListView.builder(
        controller: scrollController,
        itemCount: ouputs.value.length,
        shrinkWrap: true,
        prototypeItem: SelectableText(ouputs.value.first),
        itemBuilder: (context, index) {
          return SelectableText(ouputs.value[index]);
        },
      ),
    );
  }
}

每次添加元素时,此代码都会向下滚动到ListView.builder的底部。
我希望只有当用户已经在ListView的底部时,scrollController才能向下滚动ListView(比如facebook上的聊天)。
我知道scrollController.position.pixels得到ListView的当前位置,scrollController.position.maxScrollExtent得到ListView的总高度。所以如果我能找到最后一个元素的高度,我可以这样做:

scrollDown() {
  if (scrollController.hasClients &&
      scrollController.position.pixels + [lastElementHeight] == scrollController.position.maxScrollExtent
  ) {
    scrollController.jumpTo(scrollController.position.maxScrollExtent);
  }
}

我该怎么做?

kmbjn2e3

kmbjn2e31#

比较scrollController.position.pixelsscrollController.position.maxScrollExtent。如果它们近似相等(考虑浮点误差的小增量),则意味着用户处于底部
示例

scrollDown() {
  if (scrollController.hasClients) {
    double currentPosition = scrollController.position.pixels;
    double maxScrollExtent = scrollController.position.maxScrollExtent;

    // Define a small delta to account for floating point errors
    double delta = 1.0;

    // Check if the user is at the bottom of the ListView
    if (currentPosition >= maxScrollExtent - delta) {
      scrollController.jumpTo(maxScrollExtent);
    }
  }
}

我没有尝试,但它应该在理论上工作

相关问题