Flutter-使widget在滚动视图中可视

 

以代码为例, 记录相关函数的功能:

MyCell 作为ListView 中的一个cell; 使不在或者不完全在屏幕内的cell, 展示到屏幕中. 主要实现在  handleClick() 方法中, 如下:
class MyCell extends StatefulWidget {
  final int index;

  const MyCell({Key key, this.index}) : super(key: key);
  @override
  _MyCellState createState() => _MyCellState();
}

class _MyCellState extends State<MyCell> {

  String _content = "";

  @override
  Widget build(BuildContext context) {
    var content = Container(
      color: Colors.white,
      height: 100,
      child: Column(
        children: <Widget>[
          Container(
            height: 1,
            color: Colors.black,
          ),
          Container(
            color: Colors.red,
            child: Text("${widget.index}"),
          ),
          Container(
            color: Colors.green,
            child: Text(_content),
          ),
        ],
      ),
    );

    return GestureDetector(
      onTap: () {
        handleClick();
      },
      child: content,
    );
  }

  void handleClick() {
  // 获取父级可滚动的组件(ListView) ScrollableState scrollableState
= Scrollable.of(context); ScrollPosition position = scrollableState.position;   // 当前cell所对应的渲染对象 final RenderObject object = context.findRenderObject();
  // 当前cell所在的视口(ListView) final RenderAbstractViewport viewport
= RenderAbstractViewport.of(object);
  // debug 内容 _content
= position.pixels.toString() + "\n" + viewport.getOffsetToReveal(object, 0).offset.toString() + "\n" + viewport.getOffsetToReveal(object, 1).offset.toString(); setState(() {}); double alignment;
   // 如果偏移量大于 (当前cell顶部与视口顶部之间的距离), 则当前cell靠上对齐滚入屏幕内(cell上边已经超出视口)
if (position.pixels > viewport.getOffsetToReveal(object, 0.0).offset) { // Move down to the top of the viewport alignment = 0.0;
// 如果偏移量小于 (当前cell底部与视口底部之间的距离, 可能为负), 则当前cell靠下对齐滚入屏幕内(cell下边还未进入视口内)
} else if (position.pixels < viewport.getOffsetToReveal(object, 1.0).offset){
    // Move up to the bottom of the viewport
      alignment = 1.0;
    } else {
      // No scrolling is necessary to reveal the child
      return;
    }
    position.ensureVisible(
      object,
      alignment: alignment,
      duration: Duration(milliseconds: 222),
    );

  }
}

 

讲解一下  getOffsetToReveal 函数的用法

  RevealedOffset getOffsetToReveal(RenderObject target, double alignment, { Rect rect });

target: 所需要获取渲染对象
alignment: 传 0~1
  0 子对象的位置必须尽可能靠近视口的后缘。(子对象上边 距离视口上边的距离)
  0.5
  1 子对象的位置必须尽可能靠近视口的后缘。(子对象下边 距离视口下边的距离)

 



 

 

 

参考:

https://zhuanlan.zhihu.com/p/50350480

 

Flutter 如何在 scrollview 监听子 widget    https://yeungkc.com/flutter-how-to-listen-children-inside-scrollview/

posted @ 2021-02-20 16:56  Da雪山  阅读(264)  评论(0编辑  收藏  举报