Flutter 精准滚动

2025-11-10  本文已影响0人  河马过河
  // 滚动到当前播放行(优化版:直接使用精确高度计算)
  void _scrollToCurrentLine() {
    if(!logic.isAudioPlaying.value) return;
    
    _isEditLineIndex = -1;
    // 音频播放时关闭键盘
    _transcriptFocusNode.unfocus();
    
    String lrcContent = logic.note?.lrcDescription ?? "";
    if (lrcContent.isEmpty) return;
    
    List<LrcLine> lrcLines = _getCachedLrcLines(lrcContent);
    if (lrcLines.isEmpty) return;

    int currentLineIndex = _getCurrentLineIndex(lrcLines);
    // log("dddd----_scrollToCurrentLine(optimized)----currentLineIndex:${currentLineIndex}---lastScrolled:${_lastScrolledLineIndex}");
    
    // 只有当行索引改变时才滚动,避免重复滚动导致抖动
    if (currentLineIndex >= 0 && currentLineIndex != _lastScrolledLineIndex) {
      _scrollToIndexWithPreciseHeight(currentLineIndex);
      
      setState(() {
        // 触发_buildTranscript的重新构建以更新高亮
      });
    }
  }
    // 使用Scrollable.ensureVisible精确滚动到目标item
          Scrollable.ensureVisible(
            itemKey.currentContext!,
            duration: const Duration(milliseconds: 300),
            curve: Curves.easeInOut,
            alignment: 0.5, // 将目标item滚动到可视区域50%的位置
          );

注意:如果itemKey是ListView的子item,如果item被回收会导致滚动失效

 // 备用滚动方案:通过计算位置进行滚动
  void _scrollToIndexAlternative(int targetIndex) {
    ScrollController? scrollController = PrimaryScrollController.of(context);
    if (scrollController == null || !scrollController.hasClients) return;
    
    // 估算每个item的高度
    // 包含:上下padding(33.w*2) + 播放按钮行(~60.w) + 间距(24.w) + 文本行(~60.w) = 约210.w
    double estimatedItemHeight = 210.w;
    double targetOffset = targetIndex * estimatedItemHeight;
    
    // 确保不超过最大滚动范围
    double maxOffset = scrollController.position.maxScrollExtent;
    if (targetOffset > maxOffset) {
      targetOffset = maxOffset;
    }
    
    scrollController.animateTo(
      targetOffset,
      duration: const Duration(milliseconds: 300),
      curve: Curves.easeInOut,
    );
    
    _lastScrolledLineIndex = targetIndex;
    log("dddd----_scrollToIndexAlternative----scrolled to index:${targetIndex}, offset:${targetOffset}, estimatedHeight:${estimatedItemHeight}");
  }
上一篇 下一篇

猜你喜欢

热点阅读