Skip to content

[How to use] reverse的listview中item可以展开折叠,即item的高度发生了变化,如何利用standby()保持列表位置呢? #103

@sweatfryash

Description

@sweatfryash

Platforms

Android, iOS

Description

作者你好,我的问题如标题,简单的demo我贴在了下方,如果表达不清晰的话我再补充

My code

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

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

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple),
        useMaterial3: true,
      ),
      home: const MyHomePage(title: 'Flutter Demo Home Page'),
    );
  }
}

class MyHomePage extends StatefulWidget {
  const MyHomePage({super.key, required this.title});

  final String title;

  @override
  State<MyHomePage> createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  late final scrollController = ScrollController();

  late final observerController = ListObserverController(controller: scrollController)
    ..cacheJumpIndexOffset = false;

  // 实例化 ChatScrollObserver
  late final chatObserver = ChatScrollObserver(observerController)
    // 滚动视图的偏移量超过 5 时才会启用保持IM消息位置的功能
    ..fixedPositionOffset = 5
    // 内部在切换 isShrinkWrap 的值时会触发该回调,
    // 触发时局部刷新列表视图即可,这里因为是 Demo 的缘故,做法比较简单粗暴
    ..toRebuildScrollViewCallback = () {
      setState(() {});
    };

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        backgroundColor: Theme.of(context).colorScheme.inversePrimary,
        title: Text(widget.title),
      ),
      body: ListViewObserver(
        child: ListView.builder(
          controller: scrollController,
          physics: ChatObserverClampingScrollPhysics(observer: chatObserver),
          itemCount: 20,
          reverse: true,
          itemBuilder: (context, index) {
            return ListItem(
              index: index,
              onExpand: () {
                chatObserver.standby();
              },
            );
          },
        ),
      ),
    );
  }
}

class ListItem extends StatefulWidget {
  const ListItem({super.key, required this.index, required this.onExpand});

  final int index;
  final VoidCallback onExpand;

  @override
  State<ListItem> createState() => _ListItemState();
}

class _ListItemState extends State<ListItem> {
  bool isExpand = false;

  @override
  Widget build(BuildContext context) {
    return Container(
      margin: const EdgeInsets.all(10),
      padding: const EdgeInsets.all(20),
      decoration: BoxDecoration(border: Border.all()),
      child: Column(
        mainAxisSize: MainAxisSize.min,
        children: [
          Text('${widget.index}'),
          if (isExpand)
            Container(
              color: Colors.grey,
              height: 100,
              child: const Center(
                child: Text('展开内容'),
              ),
            ),
          TextButton(
            onPressed: () {
              widget.onExpand();
              setState(() {
                isExpand = !isExpand;
              });
            },
            child: Text(isExpand ? '收起' : '展开'),
          ),
        ],
      ),
    );
  }
}

Try do it

No response

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions