| // Copyright 2014 The Flutter Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| // Template: dev/snippets/config/templates/stateful_widget_material.tmpl |
| // |
| // Comment lines marked with "▼▼▼" and "▲▲▲" are used for authoring |
| // of samples, and may be ignored if you are just exploring the sample. |
| |
| // Flutter code sample for CustomScrollView |
| // |
| //*************************************************************************** |
| //* ▼▼▼▼▼▼▼▼ description ▼▼▼▼▼▼▼▼ (do not modify or remove section marker) |
| |
| // By default, if items are inserted at the "top" of a scrolling container like |
| // [ListView] or [CustomScrollView], the top item and all of the items below it |
| // are scrolled downwards. In some applications, it's preferable to have the |
| // top of the list just grow upwards, without changing the scroll position. |
| // This example demonstrates how to do that with a [CustomScrollView] with |
| // two [SliverList] children, and the [CustomScrollView.center] set to the key |
| // of the bottom SliverList. The top one SliverList will grow upwards, and the |
| // bottom SliverList will grow downwards. |
| |
| //* ▲▲▲▲▲▲▲▲ description ▲▲▲▲▲▲▲▲ (do not modify or remove section marker) |
| //*************************************************************************** |
| |
| import 'package:flutter/material.dart'; |
| |
| void main() => runApp(const MyApp()); |
| |
| /// This is the main application widget. |
| class MyApp extends StatelessWidget { |
| const MyApp({Key? key}) : super(key: key); |
| |
| static const String _title = 'Flutter Code Sample'; |
| |
| @override |
| Widget build(BuildContext context) { |
| return const MaterialApp( |
| title: _title, |
| home: MyStatefulWidget(), |
| ); |
| } |
| } |
| |
| /// This is the stateful widget that the main application instantiates. |
| class MyStatefulWidget extends StatefulWidget { |
| const MyStatefulWidget({Key? key}) : super(key: key); |
| |
| @override |
| State<MyStatefulWidget> createState() => _MyStatefulWidgetState(); |
| } |
| |
| /// This is the private State class that goes with MyStatefulWidget. |
| class _MyStatefulWidgetState extends State<MyStatefulWidget> { |
| //******************************************************************** |
| //* ▼▼▼▼▼▼▼▼ code ▼▼▼▼▼▼▼▼ (do not modify or remove section marker) |
| |
| List<int> top = <int>[]; |
| List<int> bottom = <int>[0]; |
| |
| @override |
| Widget build(BuildContext context) { |
| const Key centerKey = ValueKey<String>('bottom-sliver-list'); |
| return Scaffold( |
| appBar: AppBar( |
| title: const Text('Press on the plus to add items above and below'), |
| leading: IconButton( |
| icon: const Icon(Icons.add), |
| onPressed: () { |
| setState(() { |
| top.add(-top.length - 1); |
| bottom.add(bottom.length); |
| }); |
| }, |
| ), |
| ), |
| body: CustomScrollView( |
| center: centerKey, |
| slivers: <Widget>[ |
| SliverList( |
| delegate: SliverChildBuilderDelegate( |
| (BuildContext context, int index) { |
| return Container( |
| alignment: Alignment.center, |
| color: Colors.blue[200 + top[index] % 4 * 100], |
| height: 100 + top[index] % 4 * 20.0, |
| child: Text('Item: ${top[index]}'), |
| ); |
| }, |
| childCount: top.length, |
| ), |
| ), |
| SliverList( |
| key: centerKey, |
| delegate: SliverChildBuilderDelegate( |
| (BuildContext context, int index) { |
| return Container( |
| alignment: Alignment.center, |
| color: Colors.blue[200 + bottom[index] % 4 * 100], |
| height: 100 + bottom[index] % 4 * 20.0, |
| child: Text('Item: ${bottom[index]}'), |
| ); |
| }, |
| childCount: bottom.length, |
| ), |
| ), |
| ], |
| ), |
| ); |
| } |
| |
| //* ▲▲▲▲▲▲▲▲ code ▲▲▲▲▲▲▲▲ (do not modify or remove section marker) |
| //******************************************************************** |
| |
| } |