Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to achieve ListView smooth scrolling in Flutter

I have created a list view with network images and when I am trying to scroll the listview it's scrolling is not smooths it feels like jerking. For caching I have used cached_network_image: any, this library itself working fine but listview is not getting scrolled smooth.

I know we can achieve this with Future widget but dont know how to return cached image with 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),
);
}



}

Edit: After changing build configuration to Release still same, jerking.

like image 650
user3686123 Avatar asked Feb 20 '19 12:02

user3686123


People also ask

How do I scroll smoothly?

Open your Chrome browser and input about:flags or chrome://flags in the address bar, and press Enter . Type Smooth Scrolling in the search box. Click the dropdown before Smooth Scrolling and select Enabled. Now, click the Relaunch button to restart your browser.

Is ListView builder scrollable?

builder creates a scrollable, linear array of widgets.

What is BouncingScrollPhysics flutter?

BouncingScrollPhysics class Null safety. Scroll physics for environments that allow the scroll offset to go beyond the bounds of the content, but then bounce the content back to the edge of those bounds. This is the behavior typically seen on iOS.


3 Answers

I was also looking at it for a month and after a lot of research I found a single line code that makes a listview or any list a buttery smooth scrolling

Just use physics property as physics: BouncingScrollPhysics(), and feel the difference

also if you want it for a Column you can use Singlechildscrollview and in that, you can use the physics property.

like image 177
Rohan Avatar answered Oct 19 '22 20:10

Rohan


2 things

  • consider using FadeInImage.memoryNetwork instead of cached_network_image, and/or
  • consider using ListView(children: List<Widget> ) instead of ListView.separated(itemBuilder: )

FadeInImage.memoryNetwork

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

When running your example code, I can't help to notice that cached_network_image doing some image rescaling/sampling affecting main UI thread, it's likely that this package is doing computational-heavy task on main thread. Using the official cooking book yields better result for me (Android emulator), full sample code (you may want to change kTransparentImage to some other loading icon)

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> )

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

Secondly, if you know in advance that you are going to have this finite not-so-long list, maybe you want to use ListView(children: List<Widget> ) instead of ListView.separated(itemBuilder: ), because itemBuilder will invoke/call the functions more often, and right now images are cached (either by FadeInImage.memoryNetwork or cached_network_image) for full content only, not for thumbnail, @user1462442 mention source image size, and I agree with that assessment. What we can do is to reduce the invocation to a number as low as possible.

E.g code:

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(),
      ),
    );
  }
}

As said, you can apply both of these recommendations as well.

like image 14
TruongSinh Avatar answered Oct 19 '22 22:10

TruongSinh


Try adding this to your listview:

 physics: const AlwaysScrollableScrollPhysics(),

If you are testing on an emulator, I suggest to build the release APK, install the APK on your Android phone and check to see if it is still jerky. Emulator are resource hogging, so it might be a cause.

Lastly, you can try to reduce the image numbers, image types or size to see if it is still laggy.

Else report this issue at github, so that the flutter team is aware.

like image 1
CY The Web3 Collector Avatar answered Oct 19 '22 20:10

CY The Web3 Collector