0

I am implementing a chat and there is a problem when items removes from list. If I delete several items from bottom of the CustomScrollView, the scroll position offsets up depending on sum of height of deleting items. How can I prevent it?

import 'package:flutter/material.dart';

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

class MyApp extends StatelessWidget {
  const MyApp({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return const MaterialApp(
      home: MyStatefulWidget(),
    );
  }
}

class MyStatefulWidget extends StatefulWidget {
  const MyStatefulWidget({Key? key}) : super(key: key);

  @override
  State<MyStatefulWidget> createState() => _MyStatefulWidgetState();
}

class _MyStatefulWidgetState extends State<MyStatefulWidget> {
  List<int> list = List.generate(30, (i) => i + 1).reversed.toList();

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        leading: IconButton(
          icon: const Icon(Icons.clear),
          onPressed: () {
            setState(() {
              list.removeRange(0, 5);
            });
          },
        ),
      ),
      body: CustomScrollView(
        reverse: true,
        slivers: <Widget>[
          SliverList(
            delegate: SliverChildBuilderDelegate(
              (BuildContext context, int index) {
                return Container(
                  alignment: Alignment.center,
                  color: Colors.blue[200 + list[index] % 4 * 100],
                  height: 100,
                  child: Text('Item: ${list[index]}'),
                );
              },
              childCount: list.length,
            ),
          ),
        ],
      ),
    );
  }
}
Aleksey
  • 15
  • 5

1 Answers1

0

You can use

shrinkWrap: true,

to solve your problem.

It would look like this then:

class _MyStatefulWidgetState extends State<MyStatefulWidget> {
  List<int> list = List.generate(30, (i) => i + 1).reversed.toList();

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        leading: IconButton(
          icon: const Icon(Icons.clear),
          onPressed: () {
            setState(() {
              list.removeRange(0, 5);
            });
          },
        ),
      ),
      body: CustomScrollView(
        reverse: true,
        shrinkWrap: true,    // This line has changed
        slivers: <Widget>[
          SliverList(
            delegate: SliverChildBuilderDelegate(
              (BuildContext context, int index) {
                return Container(
                  alignment: Alignment.center,
                  color: Colors.blue[200 + list[index] % 4 * 100],
                  height: 100,
                  child: Text('Item: ${list[index]}'),
                );
              },
              childCount: list.length,
            ),
          ),
        ],
      ),
    );
  }
}

Before: Before Image After: After Image

DEFL
  • 907
  • 7
  • 20
  • It is not working. – Aleksey Feb 20 '22 at 12:32
  • I might misunderstand your problem. Can you share additional resources on what is the exact type of the problem? With this solution it doesnt show the space on top – DEFL Feb 20 '22 at 12:34
  • I can`t use shrinkWrap because it is a chat with many messages. – Aleksey Feb 20 '22 at 12:38
  • If we delete items the viewport shouldn`t offsets up, e.g. if the item #10 on top of the screen after deleting 5 items the item #10 should be on top of the screen. – Aleksey Feb 20 '22 at 12:43