Flutter FutureBuilder方法&x27;FindEnderObject';被调用为空

Flutter FutureBuilder方法&x27;FindEnderObject';被调用为空,flutter,richtext,Flutter,Richtext,我想将FutureBuilder生成的RichText的位置呈现为下面的代码,我在initState()中使用了WidgetsBinding.instance.addPostFrameCallback,但我遇到了一个错误:方法'finderNodeObject'是在null上调用的。,我在没有FutureBuilder的情况下尝试了这种方法,效果很好,我不知道如何用FutureBuilder解决这个问题 class BookScreen extends StatefulWidget { in

我想将FutureBuilder生成的RichText的位置呈现为下面的代码,我在
initState()
中使用了
WidgetsBinding.instance.addPostFrameCallback
,但我遇到了一个错误:
方法'finderNodeObject'是在null上调用的。
,我在没有FutureBuilder的情况下尝试了这种方法,效果很好,我不知道如何用FutureBuilder解决这个问题

class BookScreen extends StatefulWidget {
  int bookId;
  BookScreen(this.bookId);

  @override
  _BookScreenState createState() => _BookScreenState();
}

class _BookScreenState extends State<BookScreen> {

  final GlobalKey _itemKey = GlobalKey();

void initState() {
    super.initState();

WidgetsBinding.instance.addPostFrameCallback((_) {findRichText();});

  }
@override
  Widget build(BuildContext context) {

return FutureBuilder(
      future: Provider.of<Book>(context, listen: false)
          .getBookDetail(widget.bookId),
      builder: (ctx, snapshot) => snapshot.connectionState == ConnectionState.waiting
              ? Center(
                  child: CircularProgressIndicator(),
                )
              : ListView(
                  children: <Widget>[
                    Padding(
                      padding: const EdgeInsets.all(10.0),
                      child: RichText(
                        key: _itemKey, // Here is the global key
                        text: TextSpan(
                          children: _getTextSpan(snapshot.data),
                        ),
                      ),
                   ),
                ],
             ),
          );

void findRichText() {
    var richText = _itemKey.currentContext.findRenderObject() as RenderParagraph;
    print(richText.localToGlobal(Offset.zero));
}
class BookScreen扩展StatefulWidget{
国际图书编号;
书架(this.bookId);
@凌驾
_BookScreenState createState()=>\u BookScreenState();
}
类_BookScreenState扩展状态{
最终的GlobalKey _itemKey=GlobalKey();
void initState(){
super.initState();
WidgetsBinding.instance.addPostFrameCallback((41;{findRichText();});
}
@凌驾
小部件构建(构建上下文){
回归未来建设者(
future:Provider.of(上下文,侦听:false)
.getBookDetail(widget.bookId),
生成器:(ctx,快照)=>snapshot.connectionState==connectionState.waiting
?中心(
子对象:CircularProgressIndicator(),
)
:ListView(
儿童:[
填充物(
填充:常数边集全部(10.0),
孩子:RichText(
key:\u itemKey,//这是全局密钥
text:TextSpan(
子项:_getTextSpan(snapshot.data),
),
),
),
],
),
);
void findRichText(){
var richText=_itemKey.currentContext.finderObject()作为RenderParagraph;
打印(richText.localToGlobal(Offset.zero));
}
可以在文本呈现后查询文本位置

例如,您可以将
ListView
移动到一个单独的小部件。当调用postframe回调时,文本将已经存在,因此您将获得其位置

class\u BookScreenState扩展状态{
@凌驾
小部件构建(构建上下文){
回归未来建设者(
未来:。。。,
生成器:(ctx,快照)=>
snapshot.connectionState==connectionState.waiting
?中心(子项:循环压缩机指示器())
:BooksList(数据:snapshot.data),
);
}
}
类BooksList扩展StatefulWidget{
最终数据;
BooksList({@required this.data});
@凌驾
_BookListState createState()=>\u BookListState();
}
类_BooksListState扩展状态{
最终的GlobalKey _itemKey=GlobalKey();
@凌驾
小部件构建(构建上下文){
返回列表视图(
儿童:[
RichText(
键:_itemKey,
text:TextSpan(
子项:_getTextSpan(widget.data),
),
),
],
);
}
void initState(){
super.initState();
WidgetsBinding.instance.addPostFrameCallback((){
findRichText();
});
}
void findRichText(){
var richText=_itemKey.currentContext.finderObject()作为RenderParagraph;
打印(richText.localToGlobal(Offset.zero));
}
}

然而,这种方法使代码复杂化,而且似乎不可靠

或者,如果要滚动到listview项,可以使用。它提供了更多声明性api:

final ItemScrollController ItemScrollController=ItemScrollController();
ScrollablePositionedList.builder(
itemCount:。。。,
itemBuilder:(上下文,索引)=>。。。,
itemScrollController:itemScrollController,
);
itemScrollController.jumpTo(
索引:100,
线形:0.5,
);
可以在文本呈现后查询文本位置

例如,您可以将
ListView
移动到一个单独的小部件。当调用postframe回调时,文本将已经存在,因此您将获得其位置

class\u BookScreenState扩展状态{
@凌驾
小部件构建(构建上下文){
回归未来建设者(
未来:。。。,
生成器:(ctx,快照)=>
snapshot.connectionState==connectionState.waiting
?中心(子项:循环压缩机指示器())
:BooksList(数据:snapshot.data),
);
}
}
类BooksList扩展StatefulWidget{
最终数据;
BooksList({@required this.data});
@凌驾
_BookListState createState()=>\u BookListState();
}
类_BooksListState扩展状态{
最终的GlobalKey _itemKey=GlobalKey();
@凌驾
小部件构建(构建上下文){
返回列表视图(
儿童:[
RichText(
键:_itemKey,
text:TextSpan(
子项:_getTextSpan(widget.data),
),
),
],
);
}
void initState(){
super.initState();
WidgetsBinding.instance.addPostFrameCallback((){
findRichText();
});
}
void findRichText(){
var richText=_itemKey.currentContext.finderObject()作为RenderParagraph;
打印(richText.localToGlobal(Offset.zero));
}
}

然而,这种方法使代码复杂化,而且似乎不可靠

或者,如果要滚动到listview项,可以使用。它提供了更多声明性api:

final ItemScrollController ItemScrollController=ItemScrollController();
ScrollablePositionedList.builder(
itemCount:。。。,
itemBuilder:(上下文,索引)=>。。。,
itemScrollController:itemScrollController,
);
itemScrollController.jumpTo(
索引:100,
线形:0.5,
);

findRichText
被称为“帧后”。此时,
RichText
还不存在。
CircularProgressIndicator
显示,因为数据仍在加载。使用文本的位置,您希望实现什么?我有菜单,我想在单击菜单时滚动到该位置,请如何将其实现到框架之前的RichText?
FindRightText被称为“帧后”。此时
RichText