• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1// Copyright 2018 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4import 'dart:async';
5import 'dart:math' show Random;
6
7import 'package:flutter/cupertino.dart';
8
9import '../../gallery/demo.dart';
10
11class CupertinoRefreshControlDemo extends StatefulWidget {
12  static const String routeName = '/cupertino/refresh';
13
14  @override
15  _CupertinoRefreshControlDemoState createState() => _CupertinoRefreshControlDemoState();
16}
17
18class _CupertinoRefreshControlDemoState extends State<CupertinoRefreshControlDemo> {
19  List<List<String>> randomizedContacts;
20
21  @override
22  void initState() {
23    super.initState();
24    repopulateList();
25  }
26
27  void repopulateList() {
28    final Random random = Random();
29    randomizedContacts = List<List<String>>.generate(
30      100,
31      (int index) {
32        return contacts[random.nextInt(contacts.length)]
33            // Randomly adds a telephone icon next to the contact or not.
34            ..add(random.nextBool().toString());
35      },
36    );
37  }
38
39  @override
40  Widget build(BuildContext context) {
41    return DefaultTextStyle(
42      style: CupertinoTheme.of(context).textTheme.textStyle,
43      child: CupertinoPageScaffold(
44        child: DecoratedBox(
45          decoration: BoxDecoration(
46            color: CupertinoTheme.of(context).brightness == Brightness.light
47                ? CupertinoColors.extraLightBackgroundGray
48                : CupertinoColors.darkBackgroundGray,
49          ),
50          child: CustomScrollView(
51            // If left unspecified, the [CustomScrollView] appends an
52            // [AlwaysScrollableScrollPhysics]. Behind the scene, the ScrollableState
53            // will attach that [AlwaysScrollableScrollPhysics] to the output of
54            // [ScrollConfiguration.of] which will be a [ClampingScrollPhysics]
55            // on Android.
56            // To demonstrate the iOS behavior in this demo and to ensure that the list
57            // always scrolls, we specifically use a [BouncingScrollPhysics] combined
58            // with a [AlwaysScrollableScrollPhysics]
59            physics: const BouncingScrollPhysics(parent: AlwaysScrollableScrollPhysics()),
60            slivers: <Widget>[
61              CupertinoSliverNavigationBar(
62                largeTitle: const Text('Refresh'),
63                // We're specifying a back label here because the previous page
64                // is a Material page. CupertinoPageRoutes could auto-populate
65                // these back labels.
66                previousPageTitle: 'Cupertino',
67                trailing: CupertinoDemoDocumentationButton(CupertinoRefreshControlDemo.routeName),
68              ),
69              CupertinoSliverRefreshControl(
70                onRefresh: () {
71                  return Future<void>.delayed(const Duration(seconds: 2))
72                      ..then<void>((_) {
73                        if (mounted) {
74                          setState(() => repopulateList());
75                        }
76                      });
77                },
78              ),
79              SliverSafeArea(
80                top: false, // Top safe area is consumed by the navigation bar.
81                sliver: SliverList(
82                  delegate: SliverChildBuilderDelegate(
83                    (BuildContext context, int index) {
84                      return _ListItem(
85                        name: randomizedContacts[index][0],
86                        place: randomizedContacts[index][1],
87                        date: randomizedContacts[index][2],
88                        called: randomizedContacts[index][3] == 'true',
89                      );
90                    },
91                    childCount: 20,
92                  ),
93                ),
94              ),
95            ],
96          ),
97        ),
98      ),
99    );
100  }
101}
102
103List<List<String>> contacts = <List<String>>[
104  <String>['George Washington', 'Westmoreland County', ' 4/30/1789'],
105  <String>['John Adams', 'Braintree', ' 3/4/1797'],
106  <String>['Thomas Jefferson', 'Shadwell', ' 3/4/1801'],
107  <String>['James Madison', 'Port Conway', ' 3/4/1809'],
108  <String>['James Monroe', 'Monroe Hall', ' 3/4/1817'],
109  <String>['Andrew Jackson', 'Waxhaws Region South/North', ' 3/4/1829'],
110  <String>['John Quincy Adams', 'Braintree', ' 3/4/1825'],
111  <String>['William Henry Harrison', 'Charles City County', ' 3/4/1841'],
112  <String>['Martin Van Buren', 'Kinderhook New', ' 3/4/1837'],
113  <String>['Zachary Taylor', 'Barboursville', ' 3/4/1849'],
114  <String>['John Tyler', 'Charles City County', ' 4/4/1841'],
115  <String>['James Buchanan', 'Cove Gap', ' 3/4/1857'],
116  <String>['James K. Polk', 'Pineville North', ' 3/4/1845'],
117  <String>['Millard Fillmore', 'Summerhill New', '7/9/1850'],
118  <String>['Franklin Pierce', 'Hillsborough New', ' 3/4/1853'],
119  <String>['Andrew Johnson', 'Raleigh North', ' 4/15/1865'],
120  <String>['Abraham Lincoln', 'Sinking Spring', ' 3/4/1861'],
121  <String>['Ulysses S. Grant', 'Point Pleasant', ' 3/4/1869'],
122  <String>['Rutherford B. Hayes', 'Delaware', ' 3/4/1877'],
123  <String>['Chester A. Arthur', 'Fairfield', ' 9/19/1881'],
124  <String>['James A. Garfield', 'Moreland Hills', ' 3/4/1881'],
125  <String>['Benjamin Harrison', 'North Bend', ' 3/4/1889'],
126  <String>['Grover Cleveland', 'Caldwell New', ' 3/4/1885'],
127  <String>['William McKinley', 'Niles', ' 3/4/1897'],
128  <String>['Woodrow Wilson', 'Staunton', ' 3/4/1913'],
129  <String>['William H. Taft', 'Cincinnati', ' 3/4/1909'],
130  <String>['Theodore Roosevelt', 'New York City New', ' 9/14/1901'],
131  <String>['Warren G. Harding', 'Blooming Grove', ' 3/4/1921'],
132  <String>['Calvin Coolidge', 'Plymouth', '8/2/1923'],
133  <String>['Herbert Hoover', 'West Branch', ' 3/4/1929'],
134  <String>['Franklin D. Roosevelt', 'Hyde Park New', ' 3/4/1933'],
135  <String>['Harry S. Truman', 'Lamar', ' 4/12/1945'],
136  <String>['Dwight D. Eisenhower', 'Denison', ' 1/20/1953'],
137  <String>['Lyndon B. Johnson', 'Stonewall', '11/22/1963'],
138  <String>['Ronald Reagan', 'Tampico', ' 1/20/1981'],
139  <String>['Richard Nixon', 'Yorba Linda', ' 1/20/1969'],
140  <String>['Gerald Ford', 'Omaha', 'August 9/1974'],
141  <String>['John F. Kennedy', 'Brookline', ' 1/20/1961'],
142  <String>['George H. W. Bush', 'Milton', ' 1/20/1989'],
143  <String>['Jimmy Carter', 'Plains', ' 1/20/1977'],
144  <String>['George W. Bush', 'New Haven', ' 1/20, 2001'],
145  <String>['Bill Clinton', 'Hope', ' 1/20/1993'],
146  <String>['Barack Obama', 'Honolulu', ' 1/20/2009'],
147  <String>['Donald J. Trump', 'New York City', ' 1/20/2017'],
148];
149
150class _ListItem extends StatelessWidget {
151  const _ListItem({
152    this.name,
153    this.place,
154    this.date,
155    this.called,
156  });
157
158  final String name;
159  final String place;
160  final String date;
161  final bool called;
162
163  @override
164  Widget build(BuildContext context) {
165    return Container(
166      color: CupertinoTheme.of(context).scaffoldBackgroundColor,
167      height: 60.0,
168      padding: const EdgeInsets.only(top: 9.0),
169      child: Row(
170        children: <Widget>[
171          Container(
172            width: 38.0,
173            child: called
174                ? const Align(
175                    alignment: Alignment.topCenter,
176                    child: Icon(
177                      CupertinoIcons.phone_solid,
178                      color: CupertinoColors.inactiveGray,
179                      size: 18.0,
180                    ),
181                  )
182                : null,
183          ),
184        Expanded(
185          child: Container(
186              decoration: const BoxDecoration(
187                border: Border(
188                  bottom: BorderSide(color: Color(0xFFBCBBC1), width: 0.0),
189                ),
190              ),
191              padding: const EdgeInsets.only(left: 1.0, bottom: 9.0, right: 10.0),
192              child: Row(
193                children: <Widget>[
194                  Expanded(
195                    child: Column(
196                      crossAxisAlignment: CrossAxisAlignment.start,
197                      mainAxisAlignment: MainAxisAlignment.spaceBetween,
198                      children: <Widget>[
199                        Text(
200                          name,
201                          maxLines: 1,
202                          overflow: TextOverflow.ellipsis,
203                          style: const TextStyle(
204                            fontWeight: FontWeight.w600,
205                            letterSpacing: -0.18,
206                          ),
207                        ),
208                        Text(
209                          place,
210                          maxLines: 1,
211                          overflow: TextOverflow.ellipsis,
212                          style: const TextStyle(
213                            fontSize: 15.0,
214                            letterSpacing: -0.24,
215                            color: CupertinoColors.inactiveGray,
216                          ),
217                        ),
218                      ],
219                    ),
220                  ),
221                  Text(
222                    date,
223                    style: const TextStyle(
224                      color: CupertinoColors.inactiveGray,
225                      fontSize: 15.0,
226                      letterSpacing: -0.41,
227                    ),
228                  ),
229                  Padding(
230                    padding: const EdgeInsets.only(left: 9.0),
231                    child: Icon(
232                      CupertinoIcons.info,
233                      color: CupertinoTheme.of(context).primaryColor,
234                    ),
235                  ),
236                ],
237              ),
238            ),
239          ),
240        ],
241      ),
242    );
243  }
244}
245