Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to know if a flutter image has been seen by the user

Tags:

flutter

dart

I have an Image component in a scrollable screen. At beginning when the screen open, the image cannot be seen but you need to scroll down to view it.

How can you make sure the image is completely seen by the user after they have scrolled to it? I want to count the image impression of user.

How do you achieve this in flutter?

like image 399
zukijuki Avatar asked Dec 18 '22 17:12

zukijuki


1 Answers

I didn't have much information about your code, so this is how I solved it. The impression is only counted when the image is completely visible on the screen, you can change that using _count = expression. And I used simple Container for Image.

Take a look at this screenshot first.

enter image description here


Code

void main() => runApp(MaterialApp(home: HomePage()),);

class HomePage extends StatefulWidget {
  @override
  _HomePageState createState() => _HomePageState();
}

class _HomePageState extends State<HomePage> {
  ScrollController _scrollController;
  double _heightListTile = 56, _heightContainer = 200, _oldOffset = 0, _heightBox, _initialAdd;
  int _initialCount, _count, _previousCount = 0, _itemsInList = 4;

  @override
  void initState() {
    super.initState();
    _heightBox = ((_itemsInList) * _heightListTile) + _heightContainer;
    _scrollController = ScrollController();
    _scrollController.addListener(() {
      double offset = _scrollController.offset;
      if (offset >= _oldOffset) {
        _oldOffset = offset;
        _count = _initialCount + (offset + _initialAdd) ~/ _heightBox;
        if (_count != _previousCount) setState(() {});
        _previousCount = _count;
      }
    });

    Timer.run(() {
      bool isIos = Theme.of(context).platform == TargetPlatform.iOS;
      var screenHeight = MediaQuery.of(context).size.height - (isIos ? 100 : 80); // for non notches phone use 76 instead of 100 (it's the height of status and navigation bar)
      _initialCount = screenHeight ~/ _heightBox;
      _initialAdd = screenHeight % _heightBox;
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text(_count == null ? "Let's count" : "Images shown = ${_count}")),
      body: ListView.builder(
        itemCount: 100,
        controller: _scrollController,
        itemBuilder: (context, index) {
          if (index == 0) return Container();

          if (index != 0 && index % (_itemsInList + 1) == 0) {
            return Container(
              height: _heightContainer,
              alignment: Alignment.center,
              color: Colors.blue[(index * 20) % 1000],
              child: Text("Image #${(index + 1) ~/ 5}"),
            );
          }

          return SizedBox(height: _heightListTile, child: ListTile(title: Text("Item ${index}")));
        },
      ),
    );
  }
}
like image 129
CopsOnRoad Avatar answered Jan 12 '23 00:01

CopsOnRoad