【问题标题】:How to achieve ListView smooth scrolling in FlutterFlutter中如何实现ListView平滑滚动
【发布时间】:2019-07-14 03:45:00
【问题描述】:

我创建了一个带有网络图像的列表视图,当我尝试滚动列表视图时,它的滚动并不平滑,感觉就像在抽搐。对于缓存,我使用了 cached_network_image: any,这个库本身工作正常,但列表视图滚动不顺畅。

我知道我们可以使用 Future 小部件实现这一点,但不知道如何使用 Future 返回缓存的图像。

import 'package:flutter/material.dart';
import 'package:cached_network_image/cached_network_image.dart';

void main() {
   runApp(
      MaterialApp(
        title: 'List view with network images',
        home: ListViewController(),

     )
  );
}


class ListViewController extends StatelessWidget {

var imagesArray = [
  "http://iastro.shangcarts.com/pub/media/notice/File-1550484786.jpeg",
  "http://iastro.shangcarts.com/pub/media/notice/File-1550218043.jpg",
  "http://iastro.shangcarts.com/pub/media/notice/File-1550217808.jpeg",
  "http://iastro.shangcarts.com/pub/media/notice/File-1550111913.jpg",
  "http://iastro.shangcarts.com/pub/media/notice/File-1550108862.jpeg",
  "http://iastro.shangcarts.com/pub/media/notice/File-1550024618.jpg",
  "http://iastro.shangcarts.com/pub/media/notice/File-1550022739.jpeg",
  "http://iastro.shangcarts.com/pub/media/notice/File-1549935759.jpg",
  "http://iastro.shangcarts.com/pub/media/notice/File-1549935073.jpeg",
  "http://iastro.shangcarts.com/pub/media/notice/File-1549850545.jpg",
  "http://iastro.shangcarts.com/pub/media/notice/File-1549849978.jpeg",
  "http://iastro.shangcarts.com/pub/media/notice/File-1549008412.jpg",
  "http://iastro.shangcarts.com/pub/media/notice/File-1548985261.jpeg",
  "http://iastro.shangcarts.com/pub/media/notice/File-1548821873.jpg",
  "http://iastro.shangcarts.com/pub/media/notice/File-1548731040.jpeg",
  "http://iastro.shangcarts.com/pub/media/notice/File-1548641672.jpeg",
  "http://iastro.shangcarts.com/pub/media/notice/File-1548410089.jpg",
  "http://iastro.shangcarts.com/pub/media/notice/File-1547774905.jpg",
  "http://iastro.shangcarts.com/pub/media/notice/File-1547701178.jpg",
  "http://iastro.shangcarts.com/pub/media/notice/File-1547625318.jpg",
  "http://iastro.shangcarts.com/pub/media/notice/File-1547624883.jpg",
  "http://iastro.shangcarts.com/pub/media/notice/File-1547619153.jpg",
  "http://iastro.shangcarts.com/pub/media/notice/File-1547606341.jpg",
  "http://iastro.shangcarts.com/pub/media/notice/File-1547606200.jpg",
  "http://iastro.shangcarts.com/pub/media/notice/File-1547603338.jpg",
  "http://iastro.shangcarts.com/pub/media/notice/File-1547602464.jpg",
  "http://iastro.shangcarts.com/pub/media/notice/File-1547454842.jpg",
  "http://iastro.shangcarts.com/pub/media/notice/File-1547192524.jpg",
  "http://iastro.shangcarts.com/pub/media/notice/File-1547191374.jpg"
];




Widget _imageCell(String imageUrl) {

return ListTile(
  leading: CachedNetworkImage(imageUrl: imageUrl, placeholder: CircularProgressIndicator(), errorWidget: Icon(Icons.error),),
);

}


@override
Widget build(BuildContext context) {
// TODO: implement build
return Material(
  child: ListView.separated(
      itemBuilder: (BuildContext context, int index) {
        return _imageCell(imagesArray[index]);
      },
      separatorBuilder: (context, index) => Divider(
        color: Colors.black,
      ),
      itemCount: imagesArray.length),
);
}



}

编辑:将构建配置更改为发布后仍然相同,抽搐。

【问题讨论】:

  • 在发布模式下检查应用程序。
  • 是的,调试模式不流畅,让它 --profile 甚至 --release

标签: flutter flutter-layout


【解决方案1】:

我也研究了一个月,经过大量研究后,我发现了一个单行代码,可以使列表视图或任何列表平滑滚动

只需使用 physics 属性作为physics: BouncingScrollPhysics(), 并感受不同

如果您希望将它用于 Column,您可以使用 Singlechildscrollview,在其中,您可以使用物理属性。

【讨论】:

    【解决方案2】:

    两件事

    • 考虑使用FadeInImage.memoryNetwork 而不是cached_network_image,和/或
    • 考虑使用ListView(children: List<Widget> ) 而不是ListView.separated(itemBuilder: )

    FadeInImage.memoryNetwork

    参考https://flutter.dev/docs/cookbook/images/fading-in-images

    在运行您的示例代码时,我不禁注意到cached_network_image 进行了一些影响主 UI 线程的图像重新缩放/采样,很可能这个包正在主线程上执行计算量大的任务。使用官方烹饪书对我来说会产生更好的结果(Android 模拟器),完整的示例代码(您可能希望将 kTransparentImage 更改为其他加载图标)

    import 'package:flutter/material.dart';
    import 'package:transparent_image/transparent_image.dart';
    
    void main() {
      runApp(MaterialApp(
        title: 'List view with network images',
        home: ListViewController(),
      ));
    }
    
    class ListViewController extends StatelessWidget {
      var imagesArray = [
        "http://iastro.shangcarts.com/pub/media/notice/File-1550484786.jpeg",
        "http://iastro.shangcarts.com/pub/media/notice/File-1550218043.jpg",
        "http://iastro.shangcarts.com/pub/media/notice/File-1550217808.jpeg",
        "http://iastro.shangcarts.com/pub/media/notice/File-1550111913.jpg",
        "http://iastro.shangcarts.com/pub/media/notice/File-1550108862.jpeg",
        "http://iastro.shangcarts.com/pub/media/notice/File-1550024618.jpg",
        "http://iastro.shangcarts.com/pub/media/notice/File-1550022739.jpeg",
        "http://iastro.shangcarts.com/pub/media/notice/File-1549935759.jpg",
        "http://iastro.shangcarts.com/pub/media/notice/File-1549935073.jpeg",
        "http://iastro.shangcarts.com/pub/media/notice/File-1549850545.jpg",
        "http://iastro.shangcarts.com/pub/media/notice/File-1549849978.jpeg",
        "http://iastro.shangcarts.com/pub/media/notice/File-1549008412.jpg",
        "http://iastro.shangcarts.com/pub/media/notice/File-1548985261.jpeg",
        "http://iastro.shangcarts.com/pub/media/notice/File-1548821873.jpg",
        "http://iastro.shangcarts.com/pub/media/notice/File-1548731040.jpeg",
        "http://iastro.shangcarts.com/pub/media/notice/File-1548641672.jpeg",
        "http://iastro.shangcarts.com/pub/media/notice/File-1548410089.jpg",
        "http://iastro.shangcarts.com/pub/media/notice/File-1547774905.jpg",
        "http://iastro.shangcarts.com/pub/media/notice/File-1547701178.jpg",
        "http://iastro.shangcarts.com/pub/media/notice/File-1547625318.jpg",
        "http://iastro.shangcarts.com/pub/media/notice/File-1547624883.jpg",
        "http://iastro.shangcarts.com/pub/media/notice/File-1547619153.jpg",
        "http://iastro.shangcarts.com/pub/media/notice/File-1547606341.jpg",
        "http://iastro.shangcarts.com/pub/media/notice/File-1547606200.jpg",
        "http://iastro.shangcarts.com/pub/media/notice/File-1547603338.jpg",
        "http://iastro.shangcarts.com/pub/media/notice/File-1547602464.jpg",
        "http://iastro.shangcarts.com/pub/media/notice/File-1547454842.jpg",
        "http://iastro.shangcarts.com/pub/media/notice/File-1547192524.jpg",
        "http://iastro.shangcarts.com/pub/media/notice/File-1547191374.jpg"
      ];
    
      Widget _imageCell(String imageUrl) {
        return ListTile(
            leading: FadeInImage.memoryNetwork(
          placeholder: kTransparentImage,
          image: imageUrl,
        ));
      }
    
      @override
      Widget build(BuildContext context) {
    // TODO: implement build
        return Material(
          child: 
          ListView.separated(
              itemBuilder: (BuildContext context, int index) {
                return _imageCell(imagesArray[index]);
              },
              separatorBuilder: (context, index) => Divider(
                    color: Colors.black,
                  ),
              itemCount: imagesArray.length),
        );
      }
    }
    

    ListView(children: List<Widget> )

    参考https://docs.flutter.io/flutter/widgets/ListView-class.html

    其次,如果您事先知道您将拥有这个有限的不太长的列表,也许您想使用ListView(children: List<Widget> ) 而不是ListView.separated(itemBuilder: ),因为itemBuilder 将调用/调用更多函数通常,现在图像被缓存(通过FadeInImage.memoryNetworkcached_network_image)仅用于完整内容,不用于缩略图,@user1462442 提及源图像大小,我同意该评估。我们能做的就是尽可能减少调用次数。

    例如代码:

    import 'package:flutter/material.dart';
    import 'package:cached_network_image/cached_network_image.dart';
    
    void main() {
      runApp(MaterialApp(
        title: 'List view with network images',
        home: ListViewController(),
      ));
    }
    
    class ListViewController extends StatelessWidget {
      var imagesArray = [
        "http://iastro.shangcarts.com/pub/media/notice/File-1550484786.jpeg",
        "http://iastro.shangcarts.com/pub/media/notice/File-1550218043.jpg",
        "http://iastro.shangcarts.com/pub/media/notice/File-1550217808.jpeg",
        "http://iastro.shangcarts.com/pub/media/notice/File-1550111913.jpg",
        "http://iastro.shangcarts.com/pub/media/notice/File-1550108862.jpeg",
        "http://iastro.shangcarts.com/pub/media/notice/File-1550024618.jpg",
        "http://iastro.shangcarts.com/pub/media/notice/File-1550022739.jpeg",
        "http://iastro.shangcarts.com/pub/media/notice/File-1549935759.jpg",
        "http://iastro.shangcarts.com/pub/media/notice/File-1549935073.jpeg",
        "http://iastro.shangcarts.com/pub/media/notice/File-1549850545.jpg",
        "http://iastro.shangcarts.com/pub/media/notice/File-1549849978.jpeg",
        "http://iastro.shangcarts.com/pub/media/notice/File-1549008412.jpg",
        "http://iastro.shangcarts.com/pub/media/notice/File-1548985261.jpeg",
        "http://iastro.shangcarts.com/pub/media/notice/File-1548821873.jpg",
        "http://iastro.shangcarts.com/pub/media/notice/File-1548731040.jpeg",
        "http://iastro.shangcarts.com/pub/media/notice/File-1548641672.jpeg",
        "http://iastro.shangcarts.com/pub/media/notice/File-1548410089.jpg",
        "http://iastro.shangcarts.com/pub/media/notice/File-1547774905.jpg",
        "http://iastro.shangcarts.com/pub/media/notice/File-1547701178.jpg",
        "http://iastro.shangcarts.com/pub/media/notice/File-1547625318.jpg",
        "http://iastro.shangcarts.com/pub/media/notice/File-1547624883.jpg",
        "http://iastro.shangcarts.com/pub/media/notice/File-1547619153.jpg",
        "http://iastro.shangcarts.com/pub/media/notice/File-1547606341.jpg",
        "http://iastro.shangcarts.com/pub/media/notice/File-1547606200.jpg",
        "http://iastro.shangcarts.com/pub/media/notice/File-1547603338.jpg",
        "http://iastro.shangcarts.com/pub/media/notice/File-1547602464.jpg",
        "http://iastro.shangcarts.com/pub/media/notice/File-1547454842.jpg",
        "http://iastro.shangcarts.com/pub/media/notice/File-1547192524.jpg",
        "http://iastro.shangcarts.com/pub/media/notice/File-1547191374.jpg"
      ];
    
      Widget _imageCell(String imageUrl) {
        return ListTile(
          leading: CachedNetworkImage(
            imageUrl: imageUrl,
            placeholder: CircularProgressIndicator(),
            errorWidget: Icon(Icons.error),
          ),
        );
      }
    
      @override
      Widget build(BuildContext context) {
    // TODO: implement build
        return Material(
          child: ListView(
            children: imagesArray.map((imageUrl) => _imageCell(imageUrl)).toList(),
          ),
        );
      }
    }
    

    如上所述,您也可以同时应用这两个建议。

    【讨论】:

    • 我选择了 ListView/children 路线,因为我的列表同样“小”。固定。
    • FadeInImage.memoryNetwork 似乎没有缓存图像。如果您关闭应用程序并重新打开,图像将再次从网络加载,而在 CachedImageNetwork 中,图像将立即从缓存中加载。这是预期的行为吗?
    【解决方案3】:

    尝试将其添加到您的列表视图中:

     physics: const AlwaysScrollableScrollPhysics(),
    

    如果您在模拟器上进行测试,我建议您构建发布版 APK,在您的 Android 手机上安装 APK 并检查它是否仍然不稳定。模拟器是资源占用,所以这可能是一个原因。

    最后,您可以尝试减少图像数量、图像类型或大小,看看是否仍然滞后。

    在 github 上报告这个问题,以便 Flutter 团队知道。

    【讨论】:

      【解决方案4】:

      除了减小源图像大小之外,我认为目前没有好的解决方案。我看了你的图片列表,有些图片非常大。

      https://github.com/renefloor/flutter_cached_network_image/issues/90

      https://github.com/pejalo/flutter_image_performance

      https://github.com/flutter/flutter/issues/25469

      https://github.com/flutter/flutter/issues/27625#issuecomment-461677587

      https://github.com/flutter/flutter/issues/2848

      https://github.com/flutter/flutter/issues/26194

      Flutter 缩小比例非常慢。 Flutter 团队必须针对性能进行优化。

      另外,你的代码不能在 Flutter stable 上运行

      Flutter 1.0.0 • channel stable • https://github.com/flutter/flutter.git
      Framework • revision 5391447fae (3 months ago) • 2018-11-29 19:41:26 -0800
      Engine • revision 7375a0f414
      Tools • Dart 2.1.0 (build 2.1.0-dev.9.4 f9ebf21297)
      
      Compiler message:
      lib/main.dart:56:64: Error: The argument type '#lib1::CircularProgressIndicator'
      can't be assigned to the parameter type '(#lib2::BuildContext, dart.core::String)
      → #lib2::Widget'.
      Try changing the type of the parameter, or casting the argument to
      '(#lib2::BuildContext, dart.core::String) → #lib2::Widget'.
        leading: CachedNetworkImage(imageUrl: imageUrl, placeholder:
        CircularProgressIndicator(), errorWidget: Icon(Icons.error),),
                                                                     ^
      lib/main.dart:56:106: Error: The argument type '#lib1::Icon' can't be assigned to
      the parameter type '(#lib2::BuildContext, dart.core::String, dart.core::Exception)
      → #lib2::Widget'.
      Try changing the type of the parameter, or casting the argument to
      '(#lib2::BuildContext, dart.core::String, dart.core::Exception) → #lib2::Widget'.
        leading: CachedNetworkImage(imageUrl: imageUrl, placeholder:
        CircularProgressIndicator(), errorWidget: Icon(Icons.error),),
                                                                                                               ^
      Compiler failed on /Users/blah/stackoverflow/issue_54786567/lib/main.dart
      Error launching application on iPhone XR.
      
      
      flutter run
      Launching lib/main.dart on iPhone XR in debug mode...
      Starting Xcode build...                                          
       ├─Assembling Flutter resources...                    3.9s
      
       └─Compiling, linking and signing...                  3.4s
      
      Xcode build done.                                            9.1s
       5.8s
      Syncing files to device iPhone XR...                             
      flutter: ══╡ EXCEPTION CAUGHT BY RENDERING LIBRARY ╞═════════════════════════════════════════════════════════
      flutter: The following assertion was thrown during performLayout():
      flutter: BoxConstraints forces an infinite height.
      flutter: These invalid constraints were provided to RenderSemanticsAnnotations's layout() function by the
      flutter: following function, which probably computed the invalid constraints in question:
      flutter:   RenderConstrainedBox.performLayout (package:flutter/src/rendering/proxy_box.dart:258:13)
      flutter: The offending constraints were:
      flutter:   BoxConstraints(w=382.0, h=Infinity)
      flutter:
      flutter: When the exception was thrown, this was the stack:
      flutter: #0      BoxConstraints.debugAssertIsValid.<anonymous closure>.throwError (package:flutter/src/rendering/box.dart:504:9)
      flutter: #1      BoxConstraints.debugAssertIsValid.<anonymous closure> (package:flutter/src/rendering/box.dart:547:21)
      flutter: #2      BoxConstraints.debugAssertIsValid (package:flutter/src/rendering/box.dart:551:6)
      flutter: #3      RenderObject.layout (package:flutter/src/rendering/object.dart:1549:24)
      flutter: #4      RenderConstrainedBox.performLayout (package:flutter/src/rendering/proxy_box.dart:258:13)
      flutter: #5      RenderObject.layout (package:flutter/src/rendering/object.dart:1634:7)
      flutter: #6      _RenderProxyBox&RenderBox&RenderObjectWithChildMixin&RenderProxyBoxMixin.performLayout (package:flutter/src/rendering/proxy_box.dart:104:13)
      flutter: #7      RenderObject.layout (package:flutter/src/rendering/object.dart:1634:7)
      flutter: #8      RenderStack.performLayout (package:flutter/src/rendering/stack.dart:510:15)
      flutter: #9      RenderObject.layout (package:flutter/src/rendering/object.dart:1634:7)
      flutter: #10     _RenderListTile._layoutBox (package:flutter/src/material/list_tile.dart:892:9)
      flutter: #11     _RenderListTile.performLayout (package:flutter/src/material/list_tile.dart:913:30)
      flutter: #12     RenderObject.layout (package:flutter/src/rendering/object.dart:1634:7)
      flutter: #13     RenderPadding.performLayout (package:flutter/src/rendering/shifted_box.dart:199:11)
      flutter: #14     RenderObject.layout (package:flutter/src/rendering/object.dart:1634:7)
      flutter: #15     _RenderProxyBox&RenderBox&RenderObjectWithChildMixin&RenderProxyBoxMixin.performLayout (package:flutter/src/rendering/proxy_box.dart:104:13)
      flutter: #16     RenderObject.layout (package:flutter/src/rendering/object.dart:1634:7)
      flutter: #17     _RenderProxyBox&RenderBox&RenderObjectWithChildMixin&RenderProxyBoxMixin.performLayout (package:flutter/src/rendering/proxy_box.dart:104:13)
      flutter: #18     RenderObject.layout (package:flutter/src/rendering/object.dart:1634:7)
      flutter: #19     _RenderProxyBox&RenderBox&RenderObjectWithChildMixin&RenderProxyBoxMixin.performLayout (package:flutter/src/rendering/proxy_box.dart:104:13)
      flutter: #20     RenderObject.layout (package:flutter/src/rendering/object.dart:1634:7)
      flutter: #21     _RenderProxyBox&RenderBox&RenderObjectWithChildMixin&RenderProxyBoxMixin.performLayout (package:flutter/src/rendering/proxy_box.dart:104:13)
      flutter: #22     RenderObject.layout (package:flutter/src/rendering/object.dart:1634:7)
      flutter: #23     _RenderProxyBox&RenderBox&RenderObjectWithChildMixin&RenderProxyBoxMixin.performLayout (package:flutter/src/rendering/proxy_box.dart:104:13)
      flutter: #24     RenderObject.layout (package:flutter/src/rendering/object.dart:1634:7)
      flutter: #25     RenderSliverList.performLayout (package:flutter/src/rendering/sliver_list.dart:164:27)
      flutter: #26     RenderObject.layout (package:flutter/src/rendering/object.dart:1634:7)
      flutter: #27     RenderSliverPadding.performLayout (package:flutter/src/rendering/sliver_padding.dart:182:11)
      flutter: #28     RenderObject.layout (package:flutter/src/rendering/object.dart:1634:7)
      flutter: #29     RenderViewportBase.layoutChildSequence (package:flutter/src/rendering/viewport.dart:405:13)
      flutter: #30     RenderViewport._attemptLayout (package:flutter/src/rendering/viewport.dart:1316:12)
      flutter: #31     RenderViewport.performLayout (package:flutter/src/rendering/viewport.dart:1234:20)
      flutter: #32     RenderObject._layoutWithoutResize (package:flutter/src/rendering/object.dart:1509:7)
      flutter: #33     PipelineOwner.flushLayout (package:flutter/src/rendering/object.dart:768:18)
      flutter: #34     _WidgetsFlutterBinding&BindingBase&GestureBinding&ServicesBinding&SchedulerBinding&PaintingBinding&SemanticsBinding&RendererBinding.drawFrame (package:flutter/src/rendering/binding.dart:281:19)
      flutter: #35     _WidgetsFlutterBinding&BindingBase&GestureBinding&ServicesBinding&SchedulerBinding&PaintingBinding&SemanticsBinding&RendererBinding&WidgetsBinding.drawFrame (package:flutter/src/widgets/binding.dart:677:13)
      flutter: #36     _WidgetsFlutterBinding&BindingBase&GestureBinding&ServicesBinding&SchedulerBinding&PaintingBinding&SemanticsBinding&RendererBinding._handlePersistentFrameCallback (package:flutter/src/rendering/binding.dart:219:5)
      flutter: #37     _WidgetsFlutterBinding&BindingBase&GestureBinding&ServicesBinding&SchedulerBinding._invokeFrameCallback (package:flutter/src/scheduler/binding.dart:990:15)
      flutter: #38     _WidgetsFlutterBinding&BindingBase&GestureBinding&ServicesBinding&SchedulerBinding.handleDrawFrame (package:flutter/src/scheduler/binding.dart:930:9)
      flutter: #39     _WidgetsFlutterBinding&BindingBase&GestureBinding&ServicesBinding&SchedulerBinding._handleDrawFrame (package:flutter/src/scheduler/binding.dart:842:5)
      flutter: #40     _invoke (dart:ui/hooks.dart:154:13)
      flutter: #41     _drawFrame (dart:ui/hooks.dart:143:3)
      flutter:
      flutter: The following RenderObject was being processed when the exception was fired:
      flutter:   RenderConstrainedBox#57507 relayoutBoundary=up12 NEEDS-LAYOUT NEEDS-PAINT
      flutter:   creator: ConstrainedBox ← Container ← FadeTransition ← Stack ← StreamBuilder<FileInfo>-[#fb1e3] ←
      flutter:   CachedNetworkImage ← IconTheme ← Builder ← _ListTile ← MediaQuery ← Padding ← SafeArea ← ⋯
      flutter:   parentData: <none> (can use size)
      flutter:   constraints: BoxConstraints(0.0<=w<=382.0, 0.0<=h<=Infinity)
      flutter:   size: MISSING
      flutter:   additionalConstraints: BoxConstraints(biggest)
      flutter: This RenderObject had the following descendants (showing up to depth 5):
      flutter:   RenderSemanticsAnnotations#494da NEEDS-LAYOUT NEEDS-PAINT
      flutter:     RenderImage#98201 NEEDS-LAYOUT NEEDS-PAINT
      flutter: ════════════════════════════════════════════════════════════════════════════════════════════════════
      flutter: Another exception was thrown: RenderBox was not laid out: RenderConstrainedBox#57507 relayoutBoundary=up12 NEEDS-PAINT
      flutter: Another exception was thrown: BoxConstraints forces an infinite height.
      flutter: Another exception was thrown: RenderBox was not laid out: RenderConstrainedBox#ac73c relayoutBoundary=up12 NEEDS-PAINT
      flutter: Another exception was thrown: BoxConstraints forces an infinite height.
      flutter: Another exception was thrown: RenderBox was not laid out: RenderConstrainedBox#95164 relayoutBoundary=up12 NEEDS-PAINT
      flutter: Another exception was thrown: BoxConstraints forces an infinite height.
      flutter: Another exception was thrown: RenderBox was not laid out: RenderConstrainedBox#9efb3 relayoutBoundary=up12 NEEDS-PAINT
      flutter: Another exception was thrown: BoxConstraints forces an infinite height.
      flutter: Another exception was thrown: RenderBox was not laid out: RenderConstrainedBox#16fcc relayoutBoundary=up12 NEEDS-PAINT
      flutter: Another exception was thrown: BoxConstraints forces an infinite height.
      

      我必须做一些修改。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-12-30
        • 2017-03-12
        • 2014-01-12
        • 1970-01-01
        相关资源
        最近更新 更多