Phoenix AzertyGamer
Phoenix AzertyGamer

Reputation: 59

Flutter How to build a CustomScrollView with a non scrollable part

I want to have a view with on top a non scrollable part like an image for example with at the bottom a tab bar that i can scroll to the top to let appear a list of item and be able to scroll inside the list of item.

For that i used a CustomScrollView, with a sliver grid in place of the image for the moment, and a sliver app bar for the tabbar and a sliverFixedExtentList for the list.

  Widget build(BuildContext context) {
return new Scaffold(
    body: new CustomScrollView(
      slivers: <Widget>[
        new SliverGrid(
          gridDelegate: new SliverGridDelegateWithFixedCrossAxisCount(
            childAspectRatio: 0.58,
            crossAxisCount: 1,

          ),
          delegate: new SliverChildBuilderDelegate(
                (BuildContext context, int index) {
              return new Container(

                  color: Colors.red,
                  child: new Container(
                    color: Colors.green,
                    child: new Text('IMG HERE'),
                  )
              );
            },
            childCount: 1,

          ),
        ),

        new SliverAppBar(
          title: new Text("title"),
          floating: false,
          pinned: true,
          primary: true,
          actions: <Widget>[
            new IconButton(
              icon: const Icon(Icons.arrow_upward),
              onPressed: () {
              },
            ),

          ],
          bottom: new TabBar(
            controller: _tabController,
            isScrollable: true,
            tabs: _bars,
          ),
        ),

        new SliverFixedExtentList(
          itemExtent: 100.0,
          delegate: new SliverChildBuilderDelegate(
                (BuildContext context, int index) {
              return new Container(
                alignment: Alignment.center,
                color: Colors.lightGreen[100 * (index % 9)],
                child: new Text('list item $index'),
              );
            },
          ),
        ),
      ],
    )
);

}

But i have 3 problems :

  1. I can't figure out how to make a sliver non scrollable for the slivergrid here.
  2. I don't know how to make the appBar be placed exactly at the botom of the screen on launch.
  3. I have a problem with the list when the appbar reach the top the list jump some items, it seems it represents the size of the sliverGrid element.

Thanks

Upvotes: 5

Views: 4929

Answers (1)

MαπμQμαπkγVπ.0
MαπμQμαπkγVπ.0

Reputation: 6729

I've tried your code and it seems that there are some missing essential parts there. I can't see what's the code behind _tabController and _bars, so I just made my own _tabController and _bars. I've run it and this is what I've got so far:

On launch: enter image description here

Browsing till the AppBar goes to the top. enter image description here

So I made some changes in your code for presentation purposes:

import 'package:flutter/material.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: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
        visualDensity: VisualDensity.adaptivePlatformDensity,
      ),
      home: MyHomePage(title: 'Flutter Demo Home Page'),
    );
  }
}

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

  final String title;

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

class _MyHomePageState extends State<MyHomePage>
    with SingleTickerProviderStateMixin {
  TabController _tabController;
  List<Widget> _bars = [
    Tab(icon: Icon(Icons.image)),
    Tab(icon: Icon(Icons.image)),
  ];
  int _selectedIndex = 0;

  @override
  void initState() {
    super.initState();
    _tabController = TabController(length: _bars.length, vsync: this);
    _tabController.addListener(() {
      setState(() {
        _selectedIndex = _tabController.index;
      });
    });
  }

  @override
  Widget build(BuildContext context) {
    return new Scaffold(
        body: new CustomScrollView(
      slivers: <Widget>[
        new SliverGrid(
          gridDelegate: new SliverGridDelegateWithFixedCrossAxisCount(
            childAspectRatio: .69,
            crossAxisCount: 1,
          ),
          delegate: new SliverChildBuilderDelegate(
            (BuildContext context, int index) {
              return SafeArea(
                child: new Container(
                  color: Colors.green,
                  child: new Text('IMG HERE'),
                ),
              );
            },
            childCount: 1,
          ),
        ),
        new SliverAppBar(
          title: new Text("title"),
          floating: false,
          pinned: true,
          primary: true,
          actions: <Widget>[
            new IconButton(
              icon: const Icon(Icons.arrow_upward),
              onPressed: () {},
            ),
          ],
          bottom: new TabBar(
            controller: _tabController,
            isScrollable: true,
            tabs: _bars,
          ),
        ),
        new SliverFixedExtentList(
          itemExtent: 100.0,
          delegate: new SliverChildBuilderDelegate(
            (BuildContext context, int index) {
              return new Container(
                alignment: Alignment.center,
                color: Colors.lightGreen[100 * (index % 9)],
                child: new Text('list item $index'),
              );
            },
          ),
        ),
      ],
    ));
  }
}

Here is the output:

enter image description here

As you can see, I've played around with the value of childAspectRatio so that you can set the AppBar` at the bottom of the screen by default, that's how I understood your question number 2.

For question number 3, it seems that your code is working fine. I am able to properly see the ascending list item from 0 sequenced properly.

And for question number 1, I am quiet confused of how you want it to happen. You don't want the SliverGrid to be scrollable but you are expecting the AppBar to be on the top of the screen after scrolling. I guess giving more context on this part could give clarity for everyone.

Upvotes: 1

Related Questions