首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

如果ListView由FutureBuilder组成,为什么PageStorageKey不工作?

ListView由FutureBuilder组成时,PageStorageKey可能不起作用的原因是,FutureBuilder在构建时可能会重新创建其子组件,导致PageStorageKey无法正确地标识子组件的状态。

PageStorageKey是用于在页面切换或重新构建时保持ListView的滚动位置和状态的关键。它通过唯一标识ListView的不同实例来实现这一点。当ListView被重新构建时,Flutter会尝试根据PageStorageKey来恢复其滚动位置和状态。

然而,当ListView由FutureBuilder组成时,FutureBuilder的builder函数会在每次Future的状态发生变化时被调用,这可能导致ListView被重新创建。由于重新创建的ListView具有不同的实例,PageStorageKey将无法正确地标识它们,从而无法正确地恢复滚动位置和状态。

为了解决这个问题,可以尝试使用AutomaticKeepAliveClientMixin来保持ListView的状态。这个mixin提供了一个keepAlive属性,将其设置为true可以确保在页面切换时保持ListView的状态。具体做法是,将ListView包装在AutomaticKeepAlive组件中,并重写wantKeepAlive方法返回true。

示例代码如下:

代码语言:txt
复制
class MyListView extends StatefulWidget {
  @override
  _MyListViewState createState() => _MyListViewState();
}

class _MyListViewState extends State<MyListView> with AutomaticKeepAliveClientMixin {
  Future<List<String>> _getData() async {
    // 获取数据的异步操作
  }

  @override
  bool get wantKeepAlive => true;

  @override
  Widget build(BuildContext context) {
    super.build(context); // 必须调用super.build

    return FutureBuilder<List<String>>(
      future: _getData(),
      builder: (context, snapshot) {
        if (snapshot.connectionState == ConnectionState.waiting) {
          return CircularProgressIndicator();
        } else if (snapshot.hasError) {
          return Text('Error: ${snapshot.error}');
        } else {
          return ListView.builder(
            key: PageStorageKey('myListView'), // 设置PageStorageKey
            itemCount: snapshot.data.length,
            itemBuilder: (context, index) {
              return ListTile(
                title: Text(snapshot.data[index]),
              );
            },
          );
        }
      },
    );
  }
}

在上面的示例中,通过将ListView包装在AutomaticKeepAlive组件中,并重写wantKeepAlive方法返回true,可以确保ListView的状态在页面切换时保持不变。同时,仍然可以使用PageStorageKey来标识ListView的实例,以便在页面切换时恢复滚动位置和状态。

腾讯云相关产品和产品介绍链接地址:

请注意,以上链接仅作为示例,具体的产品选择应根据实际需求进行评估和选择。

页面内容是否对你有帮助?
有帮助
没帮助

相关·内容

Flutter完整开发实战详解(八、 实用技巧与填坑)

1、Text 的 TextOverflow.ellipsis 生效 有时候我们为 Text 设置 ellipsis ,却发现并没有生效,而是出现如下图左边提示 overflowed 的警告。...同时你可能会发现,有时候在布局时发现布局位置不正常,居然是从状态栏开始计算,这时候你需要用 SafeArea 嵌套下,至于为什么,看源码你就会发现 MediaQueryData 的存在。...5、系统字体缩放 现在的手机一般都提供字体缩放,这给应用开发的适配上带来一定工作量,所以大多数时候我们会选择禁止应用跟随系统字体缩放。...return new Scaffold( key: new PageStorageKey(your value) ) 9、懒加载 Flutter 中通过...FutureBuilder 或者 StreamBuilder 可以和简单的实现懒加载,通过 future 或者 stream “异步” 获取数据,之后通过 AsyncSnapshot 的 data

2.4K20

我的 Flutter TDD 心路历程

怀疑和抗拒 感受不到 TDD 带来的价值,TDD 打破了常规的开发思路 觉得 TDD 繁琐,明明可以一口气实现的代码,为什么非要拆细 先写用例,但是无从下手,怎么设计用例 觉得写的用例有点傻,感觉没什么用...思考:由于「加载更多」是列表内部触发的,如果我们想知道加载什么时候结束,我们就必须拿到加载的句柄,在 Dart 中,一般我们用 Future 来表示,于是我们能想到:我们可以从外部传入一个返回 Future...的方法,列表内部获取并触发 Future,这样我们就可以从外部判断 Future 何时结束了 这个思考过程,其实是可测性的构造过程,TDD 有助于我们写出更加可测的代码,更可测的代码往往意味着设计更加合理...因此如果到了现在这个阶段,如果还不做出一些改变,那么后续写的很多用例,包括先前写的一些用例可能都要废弃。...( // 注释1:如果是加载第一页,直接触发 onLoadMore, 并将返回的 Future 传给 FutureBuilder; 如果不是第一页,将 null 返回给 FutureBuilder

1.1K20

Flutter 刷新页面:通过下拉刷新提升用户体验

还有很重要的一点需要注意,RefreshIndicator 只在垂直可滚动的 child 上才可工作,。...如果在数据获取过程中发生错误,我们应该优雅地处理并为用户提供反馈,比如展示一个错误信息或者一个 SnackBar。...比如,如果用户读一篇文章,然后更新页面,他们应该保持在原来的位置。为了实现这个,我们应该实现在刷新之后保持滚动位置的逻辑。...错误处理和用户反馈 错误处理是任何与数据源交互功能的重要一点,下来刷新也例外。当实现 onRefresh 回调,预测和处理潜在的错误至关重要,比如网络问题或者服务错误,这些会在拉取新数据时候发生。...旨在告知用户一个错误发生了,如果可能,我们还需要提供解决方案。

12610

为什么说Flutter让移动开发变得更好?

new Container( child: new CircularProgressIndicator(), ) : new ListView.builder...最重要的是,我们使用了FutureBuilder(Flutter SDK的一部分),它需要我们指定一个Future(回调)和一个构建器函数。...下面看看我是如何构建的: 该布局SliverAppBar组成,其中包含电影图像的堆叠布局,渐变,气泡和文本图层。 能够以模块化的方式表达布局使得创建这种相当复杂的布局变得非常简单。...如果用Android实现相同的事情,我必须为电影和演出分别使用不同的Activity。可以想象这让维护工作瞬间变得复杂,并且Android对于布局的共享处理方式不太灵活。...最后 如果你看到了这里,觉得文章写得不错就给个赞呗?如果你觉得那里值得改进的,请给我留言。一定会认真查询,修正不足。谢谢。

2K10

flutter中key的作用

当找到新的widget(其键和类型与相同位置的先前widget匹配),但是在前一帧的树中其他位置有一个具有相同全局键的widget时,该widget的element将移至新位置。...为什么呢?...PageStorageKey:专用于存储页面滚动位置的key。 GlobalKey:见后文。 何时使用key ValueKey 如果您有一个 Todo List 应用程序,它将会记录你需要完成的事情。...(还不如不用) PageStorageKey 当你有一个滑动列表,你通过某一个 Item 跳转到了一个新的页面,当你返回之前的列表页面时,你发现滑动的距离回到了顶部。...用途1 允许widget在应用程序中的任何位置更改其parent而丢失其状态。应用场景:在两个不同的屏幕上显示相同的widget,并保持状态相同。

1.6K10

不一样角度带你了解 Flutter 中的滑动列表实现

本篇主要帮助剖析理解 Flutter 里的列表和滑动的组成,用比较通俗易懂的方式,从常见的 ListView 到 NestedScrollView 的内部实现,帮助你更好理解和运用 Flutter 里的滑动列表...Flutter 滑动列表 在 Flutter 里我们常见的滑动列表场景,简单地说其实是三部分组成: Viewport : 它是一个 MultiChildRenderObjectWidget 的控件...⚠️注意,这里比较容易有一个误区,那就是 ListView Viewport + Scrollable 和一个RenderSliver 组成,所以在 ListView 里只会有一个 RenderSliver...NestedScrollView 为什么会把 NestedScrollView 单独拿出来说呢?这是因为 NestedScrollView 和前面介绍的滑动列表实现不大一样。 内部组成 ?...所以如果这时候额外做一些处理,那么对于 body 而言,它的 paintOrigin 还是从最顶部开始而不是固定区域的下方。 ?

2.1K41

不一样角度带你了解 Flutter 中的滑动列表实现

本篇主要帮助剖析理解 Flutter 里的列表和滑动的组成,用比较通俗易懂的方式,从常见的 ListView到 NestedScrollView 的内部实现,帮助你更好理解和运用 Flutter 里的滑动列表...Flutter 滑动列表 在 Flutter 里我们常见的滑动列表场景,简单地说其实是三部分组成: Viewport :它是一个 MultiChildRenderObjectWidget 的控件 ,「...⚠️注意,这里比较容易有一个误区,那就是 ListView 是 Viewport + Scrollable 和一个RenderSliver 组成,所以在 「ListView 里只会有一个 RenderSliver...NestedScrollView 为什么会把 NestedScrollView 单独拿出来说呢?这是因为 NestedScrollView 和前面介绍的滑动列表实现不大一样。...所以如果这时候额外做一些处理,那么对于 body 而言,它的 paintOrigin 还是从最顶部开始而不是固定区域的下方。

1K30

Flutter100行轻松实现自定义P站和油管的Logo及自由切换Logo功能

GestureDetector)分析详解 Flutter进阶篇(4)-- Flutter的Future异步详解 Flutter进阶篇(5)-- 使用Flutter创建插件详解并发布到Pub库 Flutter进阶篇(6)-- PageStorageKey...为了避免大家犯困,我这里特意准备了本文配套的两个视频,下面这个是腾讯视频的播放链接: 腾讯视频链接:Flutter100行轻松实现自定义P站和油管的Logo及自由切换Logo功能 如果你喜欢去B站观看本文配套的视频讲解..., rightBgBorderRadius: 5, rightText: 'Hub', rightTextColor: Colors.black, ), ); 如果我们只使用...image 同理把上述ListView的内容,对应的改成YouTube风格的相关配置,即可轻松实现YouTube风格的Logo样式了 效果如下图所示: ?...【Tips:】为什么要用InheritedWidget类,因为直接操作是没反应的,而使用它可以让不同层级(树形结构)的组件之间相互交操作,所以很牛逼啊,不用不行。 ?

1.2K10

ListView详细介绍与使用

类的关系图: 表现形式 这就是一种最简单的 ListView 的表现形式,黑色框就是 ListView 控件,其中一个个的 item 组成(红色框内容),然后可以通过向下滑动来查看很多的条目。...工作原理 ListView 仅是作为容器(列表),用于装载显示数据(就是上面的一个个的红色框的内容,也称为 item)。item 中的具体数据是适配器(adapter)来提供的。...试想如果把所有的数据信息全部加载到 ListView 上显示,加入这些数据有 100 条。那么 ListView 就要创建 100 个视图。...只有 item 完全离开屏幕后才会复用,这也是为什么 ListView 要创建比屏幕需要显示视图多 1 个的原因:缓冲显示视图。...ListView 提供的 xml 属性 XML 属性 说明 备注 android:divider 设置 List 列表项的分隔条(可用颜色分割,也可用图片 Drawable 分割) 设置列表之间的分割线

1.4K20

ScrollView+ListView滚动冲突,没有滑动效果 解决办法

但是在ScrollView+ListView的布局画好后,发现整个界面都无法滚动,而且ListView只显示了第一条元素。...问题分析: 上面那个提示可以看到,正常情况下ScrollView下是不允许再包含一个可滑动的View的,为什么呢?...首先要了解ScrollView的工作原理,我们常用它来布局一个内容超过当前页面,需要往下滑才能看到完整内容。...而ListView我们知道,item个数是会动态变化的,如果在ScrollView中加入ListView会让系统无法准确加载,导致了我们开始遇到的那种情况。...但是ListView只能显示部分元素,这不是我们想要的结果。 所以就需要一种方法可以根据ListView中Item数量,动态设置ListView的height,使全部item得到显示。

98910

轻松又酷炫地实现弹幕效果——手把手教学

但我想自己从设计模式、实现原理来考虑、设计,从而也可以更深刻地理解适配器模式和ListView的原理,如果您想使用RecyclerView来实现,可以自己试试。...使用时可以自己定义实体类,继承自DanmuModel ,也可以继承,只要能区分不同类型就可以:因为自己稍后的adapter中没有像ListView的Adapter一样定义了获取item类型的方法,所以就在...在Adapter中定义三个抽象方法: getViewTypeArray :获取itemView的类型type组成的数组 getSingleLineHeight :获取单行itemView的高度 getView...首先要有这样一个思路,在适配器中抽取出方法,返回itemView的高度,在弹幕View中根据弹幕绘制区域高度,除以itemView的高度,算出合理的弹幕行数(这里大家也理解了为什么在写适配器的时候要定义...判断显示位置 将所有的行分为三份,前两份行数相同,将第一份的行数四舍五入,将所有要显示弹幕的行数放入一集合中 由上至下循环判断是否有空行,有空行则直接返回,此行就是这个itemView的最佳位置 没有空行的话,下至上寻找最大空间返回

1K20

RecyclerView还能这么玩

中间部分由 2 x 2 的控件组成一个矩形。底部是类似列表的样式。 2 实现思路 我第一想法就是使用 RecyclerView 进行嵌套。...我发现自己都回答上这几个问题,所以该方案是行不通的。 我记得 ListView 能够利用下面两个方法实现多 Item 布局。 ?...作为 ListView 的替代品的 RecyclerView, 应该是支持这种实现吧。果然,不出我所料。...Adapter 的数据都是 Activity 传递过来的。我们把 RecycleView 分割为三个部分,这就需要在 MainActivity 中给 Adapter 传递三个不同泛型的 List。...有人一定会问为什么一定要选择 4 列?就不能 5 列?6 列? 很简单,因为在整个列表中,在头部中一行有 4 个控件, 1 个控件占据 1 个span。

64530

实习杂记(28):SurfaceView+ListView+MediaPlayer滑动时候灰色覆盖等问题

1.灰色覆盖,或者有一层颜色在上面 这个问题应该是   你给listView加了风格,或者给当前的Window加了风格,因为surfaceView,如果设置,应该也有一个默认的颜色值 在listView...滑动的时候,每个item应该是都会被重绘的,至少layout事件会走的,导致了surface上面有一层颜色,这个是第一个问题, 2.ListView里面出现视频画面残留 这个问题很尴尬,也是在listView...在滑动的时候,但是视频又在播放,而且如果你有切换横竖屏的话,这个问题将变得尤为严重, 具体的原因应该是这样的:本来surfaceView是在item上的,item是一个view,这个播放视频的时候,是...MediaPlayer去把视频的画面setDisplay到surfaceHolder上的, 如果播放视频的是你发生了横竖切换,导致surfaceView的大小发生了变化,MediaPlayer重新去渲染视频图片...,再回来,可能就会留有残影, 然后是如果不发生横竖屏切换,也会有残影留下来,是为什么,我想了下原因: 是因为surfaceView他有个特点,当你从window上拿到一个区域的时候,这个区域有些限制,

1.2K20

ImageLoader

super.onCreate(savedInstanceState); setContentView(R.layout.fr_image_list); ListView...listView = findViewById(R.id.listview); listView.setAdapter(new ImageAdapter()); listView.setOnItemClickListener...推荐用 FadeInBitmapDisplayer(100)//加载图片后渐入的时间 FakeBitmapDisplayer() 图片压缩质量参数 bitmapConfig(Bitmap.Config.RGB...所有的可见色都是红绿蓝组成的,所以红绿蓝又称为三原色 ALPHA_8就是Alpha8位组成--代表8位Alpha位图 ARGB_4444就是4个4位组成即16位--代表16位ARGB位图 ARGB..._8888就是4个8位组成即32位--代表32位ARGB位图 RGB_565就是R为5位,G为6位,B为5位共16位--代表16位RGB位图 位图位数越高代表其可以存储的颜色信息越多,当然图像也就越逼真

92610

Android开发之漫漫长途 XVI——ListView与RecyclerView项目实战

---- 前言 Hello,大家好,有没有想我,这一个月没有更新文章,为什么呢,大声的告诉你,,我在...(准备面试 ps:南京)。...因为毕竟本地数据的展示基本上只能作为Demo,在实际的工作以及项目中,我们遇到的问题可能要比Demo复杂的多。...面试中遇到的关于ListView以及RecyclerView的问题 第一题 ListView的缓存复用机制 还是免不得笔试啊,,起码我面试的几家公司有80%让我答一份试卷,而且给你的时间与试卷的复杂度基本上对应上...关于ListView的缓存复用机制在 Android开发之漫漫长途 XIV——ListView 一文中有非常详细的解说,这边我们就不重复说了,如果你看过我的那一篇文章,你就明白,这个事情不花个半小时是讲不清楚的...如果用RecyclerView作为根部局虽然也有许多麻烦之处,但是它带来的好处也是很明显的。

49410
领券