Bagaimana cara menampilkan indeks gulir untuk scrollController di flutter?

Aug 21 2020

Saya ingin menampilkan indeks di bagian bawah listView dengan memanfaatkan scrollController, seperti yang ditampilkan pada gambar berikut:

Setelah pengguna menggulir ke bawah, atau ke atas, jumlah di sebelah kiri, disorot dengan warna merah, bertambah / berkurang berdasarkan arah gulir pengguna.

Yang ingin saya capai adalah secara otomatis memperbarui indeks item yang ditampilkan, yang ditandai dengan warna merah pada gambar. Jadi, setiap kali pengguna menggulir ke bawah atau ke atas, indeks ini diperbarui oleh indeks item yang ditampilkan.

Gambar menunjukkan bahwa saya sudah mencapai item ke-26. Setiap kali saya menggulir ke bawah atau ke atas, indeks ini diperbarui.

Saya telah mencoba menggunakan offset yang dipancarkan untuk acara scrolling namun tidak berhasil.

Jawaban

2 Rod Aug 21 2020 at 02:23

Caranya adalah dengan menggunakan scroll controller seperti yang Anda lakukan sebelumnya.

Anda perlu menggunakan ukuran item yang diketahui dan pendengar.

// Declaring the controller and the item size
ScrollController _scrollController;
final itemSize = 100.0;

// Initializing
@override
void initState() {
  _scrollController = ScrollController();
  _scrollController.addListener(_scrollListener);
  super.initState();
}

// Your list widget (must not be nested lists)
ListView.builder(
      controller: _scrollController,
      itemCount: <Your list length>,
      itemExtent: itemSize,
      itemBuilder: (context, index) {
          return ListTile(<your items>);
      },
),

// With the listener and the itemSize, you can calculate which item
// is on screen using the provided callBack. Something like this:
void _scrollListener() {
  setState(() {
    var index = (_scrollController.offset / itemSize).round() + 1;
  });
}

Menambahkan listener ke scrollController akan memanggil callback yang diberikan setiap kali daftar di-scroll. Anda dapat menangani banyak perilaku daftar menggunakan logika yang sama, termasuk mengidentifikasi jenis peristiwa yang memicu listener, arah scroll, dll.

LouisBelmont Aug 21 2020 at 01:52

Ada lib yang disebut scroll to index yang dapat membantu Anda. Anda dapat mengambil $ index untuk ditampilkan di dalam pesan roti panggang Anda. Contoh di bawah ini berasal dari penulis lib:

import 'dart:math' as math;

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

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Scroll To Index Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: MyHomePage(title: 'Scroll To Index Demo'),
    );
  }
}

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

  final String title;

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

class _MyHomePageState extends State<MyHomePage> {
  static const maxCount = 100;
  final random = math.Random();
  final scrollDirection = Axis.vertical;

  AutoScrollController controller;
  List<List<int>> randomList;

  @override
  void initState() {
    super.initState();
    controller = AutoScrollController(
      viewportBoundaryGetter: () => Rect.fromLTRB(0, 0, 0, MediaQuery.of(context).padding.bottom),
      axis: scrollDirection
    );
    randomList = List.generate(maxCount, (index) => <int>[index, (1000 * random.nextDouble()).toInt()]);
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(widget.title),
      ),
      body: ListView(
        scrollDirection: scrollDirection,
        controller: controller,
        children: randomList.map<Widget>((data) {
          return Padding(
            padding: EdgeInsets.all(8),
            child: _getRow(data[0], math.max(data[1].toDouble(), 50.0)),
          );
        }).toList(),
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: _scrollToIndex,
        tooltip: 'Increment',
        child: Text(counter.toString()),
      ),
    );
  }

  int counter = -1;
  Future _scrollToIndex() async {
    setState(() {
      counter++;

      if (counter >= maxCount)
        counter = 0;
    });

    await controller.scrollToIndex(counter, preferPosition: AutoScrollPosition.begin);
    controller.highlight(counter);
  }

  Widget _getRow(int index, double height) {
    return _wrapScrollTag(
      index: index,
      child: Container(
        padding: EdgeInsets.all(8),
        alignment: Alignment.topCenter,
        height: height,
        decoration: BoxDecoration(
          border: Border.all(
            color: Colors.lightBlue,
            width: 4
          ),
          borderRadius: BorderRadius.circular(12)
        ),
        child: Text('index: $index, height: $height'),
      )
    );
  }

  Widget _wrapScrollTag({int index, Widget child})
  => AutoScrollTag(
    key: ValueKey(index),
    controller: controller,
    index: index,
    child: child,
    highlightColor: Colors.black.withOpacity(0.1),
  );
}
AlperenEkin Aug 21 2020 at 13:18

https://medium.com/flutter-community/create-shop-list-with-flutter-d13d3c20d68bMungkin yang satu ini bisa membantumu. Juga kode sumber tersedia. Matematika sederhana tentang tinggi item mungkin bisa membantu.