gpt4 book ai didi

flutter - 如何在不使用 GlobalKey.currentState 的情况下平滑更新 Flutter AnimatedList?

转载 作者:行者123 更新时间:2023-12-02 17:06:04 26 4
gpt4 key购买 nike

我发现的将项目插入 Flutter AnimatedList 的所有示例都利用 GlobalKey.currentState 告诉 AnimatedList 小部件已插入项目。从列表中删除也是如此。

众所周知,在 Flutter 中 GlobalKey 的 currentState 可能为 null。

就我而言,我正在等待 Firebase 消息的发送。当消息看起来被插入到 AnimatedList 的列表数据中时,如果遵循 AnimatedList 所示的流行示例,则可以使用分配的 GlobalKey.currentState 告诉 AnimatedList 新项目插入的位置。

但是,就我而言,当我尝试使用它时,GlobalKey.currentState 为 null。

否则我还能用什么?我知道我可以使用 setState,但这会导致完整的小部件刷新,在这种情况下,它显示为屏幕上的闪烁,而不是所需的 AnimatedList 插入,这是很好且平滑的。

许多人都避免使用 InheritedWidget,但我无法理解如果这是正确的技术,在这种情况下将如何实现它。

/////////
// NOTE: This is close to real code, but consider it pseudocode since it is a cut and paste from the real code less quite a bit of extra stuff I have in there. It certainly will not compile but it is representative of the issue.
/////////

class Conversation extends StatefulWidget {
Conversation({Key key, @required this.cid, this.notificationsHub}) : super(key: key);

// A bit of a hack here, but my Firebase cloud messages come through this object
MyNotificationsHub notificationsHub;

// a conversation id
final int cid;

@override
ConversationState createState() => ConversationState(cid: this.cid, notificationsHub: notificationsHub);
}

//////////

class ConversationState extends State<Conversation>
with MyNotificationsListener {
ConversationState({Key key, @required this.cid, this.notificationsHub}); // : super(key: key);

MyNotificationsHub notificationsHub;

List<ConversationFeed> feed = List();

// The GlobalKey keeps track of the visible state of the list items
// while they are being animated.
final GlobalKey<AnimatedListState> _listKey = GlobalKey();

///////////

initState() {
notificationsHub.addNotificationsListener(this);
}

///////////
// This is where the issue occurs, when a Firebase message comes in and I attempt to use the GlobalKey the currentState component is null
///////////
void receiveAlert ( MyNotificationItem alert ){
int insertIndex=0;

feed.insert(insertIndex, new ConversationFeed( alert ) );

//******* Issue below, null currentState *******
_listKey.currentState.insertItem(insertIndex);
//******* Issue above, null currentState *******
}

////////////

@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("Conversation")),
body:

new AnimatedList(

// Give the Animated list the global key
key: _listKey,

initialItemCount: feed.length,

itemBuilder: (context, index, animation) {
return ListTile(
title: Text ( feed[index].getMessageContentsString() );
})
);
}

实际结果是运行时由于GlobalKey的currentState为null而抛出空指针错误。

///更新:

我尝试使用 AnimatedList.of(context) 方法和 Builder 来解决这个问题。我尝试了以下方式:

// Declared an instance variable of BuildContext in my class definition

BuildContext acontext;

// in the Builder call I assigned it in the following manner:

body: Builder(
builder: (BuildContext zcontext) {
acontext = zcontext ;
return ( AnimatedList (....) ); }
)

// & inside my receiveAlert method I used it in the following manner:

void receiveAlert ( MyNotificationItem alert ){
....
AnimatedList.of(acontext).insertItem(insertIndex);
}

当使用上述构造时,我收到以下错误:

AnimatedList.of() called with a context that does not contain an AnimatedList.

我确信 Flutter 团队已经提供了一种触发 Widget 树外部更新的方法,我只是不确定如何实现它。也许我的技术不正确。

最佳答案

在动画列表小部件中以动画形式引入新项目时,我也遇到了同样的问题。看起来很奇怪,您可以通过检查状态是否仍然为空来解决这个问题:

if(animatedListKey.currentState != null)
animatedListKey.currentState.insertItem(0);

这意味着它不会在重建时尝试插入项目,直到状态可用。尝试一下。

您可以在此处查看我的教程中的代码:https://github.com/Morthor/flutter_todo_app_talk/blob/youtube_animatedList/lib/main.dart

关于flutter - 如何在不使用 GlobalKey.currentState 的情况下平滑更新 Flutter AnimatedList?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56896814/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com