// Copyright 2018 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. import 'dart:async'; import 'dart:math' show Random; import 'package:flutter/cupertino.dart'; import '../../gallery/demo.dart'; class CupertinoRefreshControlDemo extends StatefulWidget { static const String routeName = '/cupertino/refresh'; @override _CupertinoRefreshControlDemoState createState() => _CupertinoRefreshControlDemoState(); } class _CupertinoRefreshControlDemoState extends State<CupertinoRefreshControlDemo> { List<List<String>> randomizedContacts; @override void initState() { super.initState(); repopulateList(); } void repopulateList() { final Random random = Random(); randomizedContacts = List<List<String>>.generate( 100, (int index) { return contacts[random.nextInt(contacts.length)] // Randomly adds a telephone icon next to the contact or not. ..add(random.nextBool().toString()); }, ); } @override Widget build(BuildContext context) { return DefaultTextStyle( style: CupertinoTheme.of(context).textTheme.textStyle, child: CupertinoPageScaffold( child: DecoratedBox( decoration: BoxDecoration( color: CupertinoTheme.of(context).brightness == Brightness.light ? CupertinoColors.extraLightBackgroundGray : CupertinoColors.darkBackgroundGray, ), child: CustomScrollView( // If left unspecified, the [CustomScrollView] appends an // [AlwaysScrollableScrollPhysics]. Behind the scene, the ScrollableState // will attach that [AlwaysScrollableScrollPhysics] to the output of // [ScrollConfiguration.of] which will be a [ClampingScrollPhysics] // on Android. // To demonstrate the iOS behavior in this demo and to ensure that the list // always scrolls, we specifically use a [BouncingScrollPhysics] combined // with a [AlwaysScrollableScrollPhysics] physics: const BouncingScrollPhysics(parent: AlwaysScrollableScrollPhysics()), slivers: <Widget>[ CupertinoSliverNavigationBar( largeTitle: const Text('Refresh'), // We're specifying a back label here because the previous page // is a Material page. CupertinoPageRoutes could auto-populate // these back labels. previousPageTitle: 'Cupertino', trailing: CupertinoDemoDocumentationButton(CupertinoRefreshControlDemo.routeName), ), CupertinoSliverRefreshControl( onRefresh: () { return Future<void>.delayed(const Duration(seconds: 2)) ..then<void>((_) { if (mounted) { setState(() => repopulateList()); } }); }, ), SliverSafeArea( top: false, // Top safe area is consumed by the navigation bar. sliver: SliverList( delegate: SliverChildBuilderDelegate( (BuildContext context, int index) { return _ListItem( name: randomizedContacts[index][0], place: randomizedContacts[index][1], date: randomizedContacts[index][2], called: randomizedContacts[index][3] == 'true', ); }, childCount: 20, ), ), ), ], ), ), ), ); } } List<List<String>> contacts = <List<String>>[ <String>['George Washington', 'Westmoreland County', ' 4/30/1789'], <String>['John Adams', 'Braintree', ' 3/4/1797'], <String>['Thomas Jefferson', 'Shadwell', ' 3/4/1801'], <String>['James Madison', 'Port Conway', ' 3/4/1809'], <String>['James Monroe', 'Monroe Hall', ' 3/4/1817'], <String>['Andrew Jackson', 'Waxhaws Region South/North', ' 3/4/1829'], <String>['John Quincy Adams', 'Braintree', ' 3/4/1825'], <String>['William Henry Harrison', 'Charles City County', ' 3/4/1841'], <String>['Martin Van Buren', 'Kinderhook New', ' 3/4/1837'], <String>['Zachary Taylor', 'Barboursville', ' 3/4/1849'], <String>['John Tyler', 'Charles City County', ' 4/4/1841'], <String>['James Buchanan', 'Cove Gap', ' 3/4/1857'], <String>['James K. Polk', 'Pineville North', ' 3/4/1845'], <String>['Millard Fillmore', 'Summerhill New', '7/9/1850'], <String>['Franklin Pierce', 'Hillsborough New', ' 3/4/1853'], <String>['Andrew Johnson', 'Raleigh North', ' 4/15/1865'], <String>['Abraham Lincoln', 'Sinking Spring', ' 3/4/1861'], <String>['Ulysses S. Grant', 'Point Pleasant', ' 3/4/1869'], <String>['Rutherford B. Hayes', 'Delaware', ' 3/4/1877'], <String>['Chester A. Arthur', 'Fairfield', ' 9/19/1881'], <String>['James A. Garfield', 'Moreland Hills', ' 3/4/1881'], <String>['Benjamin Harrison', 'North Bend', ' 3/4/1889'], <String>['Grover Cleveland', 'Caldwell New', ' 3/4/1885'], <String>['William McKinley', 'Niles', ' 3/4/1897'], <String>['Woodrow Wilson', 'Staunton', ' 3/4/1913'], <String>['William H. Taft', 'Cincinnati', ' 3/4/1909'], <String>['Theodore Roosevelt', 'New York City New', ' 9/14/1901'], <String>['Warren G. Harding', 'Blooming Grove', ' 3/4/1921'], <String>['Calvin Coolidge', 'Plymouth', '8/2/1923'], <String>['Herbert Hoover', 'West Branch', ' 3/4/1929'], <String>['Franklin D. Roosevelt', 'Hyde Park New', ' 3/4/1933'], <String>['Harry S. Truman', 'Lamar', ' 4/12/1945'], <String>['Dwight D. Eisenhower', 'Denison', ' 1/20/1953'], <String>['Lyndon B. Johnson', 'Stonewall', '11/22/1963'], <String>['Ronald Reagan', 'Tampico', ' 1/20/1981'], <String>['Richard Nixon', 'Yorba Linda', ' 1/20/1969'], <String>['Gerald Ford', 'Omaha', 'August 9/1974'], <String>['John F. Kennedy', 'Brookline', ' 1/20/1961'], <String>['George H. W. Bush', 'Milton', ' 1/20/1989'], <String>['Jimmy Carter', 'Plains', ' 1/20/1977'], <String>['George W. Bush', 'New Haven', ' 1/20, 2001'], <String>['Bill Clinton', 'Hope', ' 1/20/1993'], <String>['Barack Obama', 'Honolulu', ' 1/20/2009'], <String>['Donald J. Trump', 'New York City', ' 1/20/2017'], ]; class _ListItem extends StatelessWidget { const _ListItem({ this.name, this.place, this.date, this.called, }); final String name; final String place; final String date; final bool called; @override Widget build(BuildContext context) { return Container( color: CupertinoTheme.of(context).scaffoldBackgroundColor, height: 60.0, padding: const EdgeInsets.only(top: 9.0), child: Row( children: <Widget>[ Container( width: 38.0, child: called ? const Align( alignment: Alignment.topCenter, child: Icon( CupertinoIcons.phone_solid, color: CupertinoColors.inactiveGray, size: 18.0, ), ) : null, ), Expanded( child: Container( decoration: const BoxDecoration( border: Border( bottom: BorderSide(color: Color(0xFFBCBBC1), width: 0.0), ), ), padding: const EdgeInsets.only(left: 1.0, bottom: 9.0, right: 10.0), child: Row( children: <Widget>[ Expanded( child: Column( crossAxisAlignment: CrossAxisAlignment.start, mainAxisAlignment: MainAxisAlignment.spaceBetween, children: <Widget>[ Text( name, maxLines: 1, overflow: TextOverflow.ellipsis, style: const TextStyle( fontWeight: FontWeight.w600, letterSpacing: -0.18, ), ), Text( place, maxLines: 1, overflow: TextOverflow.ellipsis, style: const TextStyle( fontSize: 15.0, letterSpacing: -0.24, color: CupertinoColors.inactiveGray, ), ), ], ), ), Text( date, style: const TextStyle( color: CupertinoColors.inactiveGray, fontSize: 15.0, letterSpacing: -0.41, ), ), Padding( padding: const EdgeInsets.only(left: 9.0), child: Icon( CupertinoIcons.info, color: CupertinoTheme.of(context).primaryColor, ), ), ], ), ), ), ], ), ); } }