我想渲染由FutureBuilder构建的RichText的位置,如下所示,我在WidgetsBinding.instance.addPostFrameCallback
中使用了initState()
,但遇到了错误:The method 'findRenderObject' was called on 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));
}
答案 0 :(得分:2)
可以在渲染后查询文本位置。
例如,您可以将ListView
移动到单独的窗口小部件。调用后帧回调时,文本将已经存在,因此您将获得其位置
class _BookScreenState extends State<BookScreen> {
@override
Widget build(BuildContext context) {
return FutureBuilder(
future: ...,
builder: (ctx, snapshot) =>
snapshot.connectionState == ConnectionState.waiting
? Center(child: CircularProgressIndicator())
: BooksList(data: snapshot.data),
);
}
}
class BooksList extends StatefulWidget {
final BooksListData data;
BooksList({@required this.data});
@override
_BooksListState createState() => _BooksListState();
}
class _BooksListState extends State<BooksList> {
final GlobalKey _itemKey = GlobalKey();
@override
Widget build(BuildContext context) {
return ListView(
children: [
RichText(
key: _itemKey,
text: TextSpan(
children: _getTextSpan(widget.data),
),
),
],
);
}
void initState() {
super.initState();
WidgetsBinding.instance.addPostFrameCallback((_) {
findRichText();
});
}
void findRichText() {
var richText = _itemKey.currentContext.findRenderObject() as RenderParagraph;
print(richText.localToGlobal(Offset.zero));
}
}
但是,这种方法使代码复杂且似乎不可靠。
或者,如果要滚动到列表视图项目,则可以使用scrollable_positioned_list package。它提供了更多的声明性api:
final ItemScrollController itemScrollController = ItemScrollController();
ScrollablePositionedList.builder(
itemCount: ...,
itemBuilder: (context, index) => ...,
itemScrollController: itemScrollController,
);
itemScrollController.jumpTo(
index: 100,
alignment: 0.5,
);