Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

how to find item in some point in ListView in Flutter?

Tags:

flutter

dart

I need to find below the point item/index in ListView? Is it possible to get it? any ListView.Builder / CustomScrollView / .... when scrolling item/index should update real-time. ex: 'Center index is $index'

this red line position can change. maybe center, maybe top/bottom/0.25/0.75...

and also item height is maybe fixed / maybe flexible

click here to view

like image 931
BIS Tech Avatar asked Oct 14 '25 13:10

BIS Tech


1 Answers

You can copy paste run full code below
You can use package https://pub.dev/packages/inview_notifier_list
With attribute isInViewPortCondition, and wrap item in InViewNotifierWidget , this allow size is flexible, see working demo
For CustomScrollView can use InViewNotifierCustomScrollView, example is here https://github.com/rvamsikrishna/inview_notifier_list/blob/master/example/lib/csv_example.dart
code snippet

isInViewPortCondition:
          (double deltaTop, double deltaBottom, double viewPortDimension) {
        return deltaTop < (0.5 * viewPortDimension) &&
            deltaBottom > (0.5 * viewPortDimension);
      },
...
InViewNotifierWidget(
        id: '$index',
        builder:
            (BuildContext context, bool isInView, Widget child) {
          if (isInView) {
            inviewIndex = index.toString();
            callback();
          }
          return Container(
              height: index.isEven? 50 : 150 ,
              width: double.infinity,
              color: Colors.blue,
              child: Text("$index ${isInView.toString()}"));
        },
      );

enter image description here

full code

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

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
        visualDensity: VisualDensity.adaptivePlatformDensity,
      ),
      home: MyHomePage(
        title: "test",
      ),
    );
  }
}

String inviewIndex = "";

class MyHomePage extends StatefulWidget {
  MyHomePage({Key key, this.title}) : super(key: key);

  final String title;

  @override
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  int _counter = 0;

  void _incrementCounter() {
    setState(() {
      _counter++;
    });
  }

  refresh() {
    WidgetsBinding.instance.addPostFrameCallback((_) {
      setState(() {});
    });
  }

  @override
  void initState() {
    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(widget.title),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            Text("Center index is $inviewIndex"),
            Expanded(
                child: ImageList(
              callback: refresh,
            ))
          ],
        ),
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: _incrementCounter,
        tooltip: 'Increment',
        child: Icon(Icons.add),
      ),
    );
  }
}

class ImageList extends StatelessWidget {
  VoidCallback callback;
  ImageList({this.callback});

  @override
  Widget build(BuildContext context) {
    return Stack(
      fit: StackFit.expand,
      children: <Widget>[
        InViewNotifierList(
          scrollDirection: Axis.vertical,
          initialInViewIds: ['0'],
          isInViewPortCondition:
              (double deltaTop, double deltaBottom, double viewPortDimension) {
            return deltaTop < (0.5 * viewPortDimension) &&
                deltaBottom > (0.5 * viewPortDimension);
          },
          itemCount: 10,
          builder: (BuildContext context, int index) {
            return Container(
              width: double.infinity,
              height: 100.0,
              alignment: Alignment.center,
              margin: EdgeInsets.symmetric(vertical: 50.0),
              child: LayoutBuilder(
                builder: (BuildContext context, BoxConstraints constraints) {
                  return InViewNotifierWidget(
                    id: '$index',
                    builder:
                        (BuildContext context, bool isInView, Widget child) {
                      if (isInView) {
                        inviewIndex = index.toString();
                        callback();
                      }
                      return Container(
                          height: index.isEven? 50 : 150 ,
                          width: double.infinity,
                          color: Colors.blue,
                          child: Text("$index ${isInView.toString()}"));
                    },
                  );
                },
              ),
            );
          },
        ),
        Align(
          alignment: Alignment.center,
          child: Container(
            height: 1.0,
            color: Colors.redAccent,
          ),
        )
      ],
    );
  }
}
like image 159
chunhunghan Avatar answered Oct 17 '25 06:10

chunhunghan