Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to use AnimatedSwitcher and CustomScrollView together

I want switch status with animation in CustomScrollView, but it throw error.

class SliverAnimatedSwitcher extends StatefulWidget {
  final state;

  const SliverAnimatedSwitcher({Key key, this.state}) : super(key: key);

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

class _SliverAnimatedSwitcherState extends State<SliverAnimatedSwitcher> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: CustomScrollView(
        slivers: <Widget>[
          SliverAppBar(
            title: Text('SliverAnimatedSwitcher'),
          ),
          _buildContent(),
        ],
      ),
    );
  }

  get state => widget.state;

  Widget _buildContent() {
    var content;
    if (state.isNotEmpty == true) {
      content = SliverList(
        delegate: SliverChildBuilderDelegate(
          (context, index) {
            var item = state.items[index];
            return ListTile(
              title: Text(item.title),
            );
          },
          childCount: state.items.length,
        ),
      );
    } else if (state.isError) {
      content = SliverFillRemaining(
        key: Key('error'),
        child: Container(alignment: Alignment.center, child: Text('Error')),
      );
    } else if (state.isLoading) {
      content = SliverFillRemaining(
        key: Key('loading'),
        child: Container(alignment: Alignment.center, child: Text('Loading')),
      );
    } else {
      content = SliverFillRemaining(
        key: Key('empty'),
        child: Container(alignment: Alignment.center, child: Text('Empty')),
      );
    }
    return AnimatedSwitcher(
      duration: Duration(milliseconds: 300),
      child: content,
    );
  }
}
like image 387
Shuai Cheng Avatar asked Oct 25 '19 03:10

Shuai Cheng


People also ask

What is CustomScrollView?

A CustomScrollView lets you supply slivers directly to create various scrolling effects, such as lists, grids, and expanding headers. For example, to create a scroll view that contains an expanding app bar followed by a list and a grid, use a list of three slivers: SliverAppBar, SliverList, and SliverGrid.

What is SliverToBoxAdapter in flutter?

SliverToBoxAdapter class Null safety. A sliver that contains a single box widget. Slivers are special-purpose widgets that can be combined using a CustomScrollView to create custom scroll effects. A SliverToBoxAdapter is a basic sliver that creates a bridge back to one of the usual box-based widgets.


2 Answers

There's a sliver_tools package on pub.dev that has a SliverAnimatedSwitcher. You'd use it like this:

SliverAnimatedSwitcher(
  duration: kThemeAnimationDuration,
  child: content,
)
like image 119
Joe Muller Avatar answered Sep 30 '22 21:09

Joe Muller


It is because sliver widget is not capable with Stack which is using as layout builder inside AnimatedSwitcher.

I found a temporary solution. Though the result is not equal to the original one (only show the last widget in the result), but I think it is acceptable for me now with such little effort.

  1. First create a SliverAnimatedSwitcher exact the same code as AnimatedSwitcher here
  2. Modify the Stack part to return the currentChild only (defaultLayoutBuilder)
  3. Change FadeTransition to SliverFadeTransition (defaultTransitionBuilder)

.

static Widget defaultLayoutBuilder(Widget currentChild, List<Widget> previousChildren) {
  return currentChild;
}

.

static Widget defaultTransitionBuilder(Widget child, Animation<double> animation) {
  return SliverFadeTransition(
    opacity: animation,
    sliver: child,
  );
}

If someone can find a way to Stack Sliver widgets above each other, the result may be more perfect.

like image 33
yellowgray Avatar answered Sep 30 '22 20:09

yellowgray