mirror of
https://github.com/flutter/samples.git
synced 2026-05-13 18:37:45 +00:00
Initialize Rolodex (#2569)
Creates the start of the Rolodex app. Sets up the app with the initial routes setup. Since the native Contacts app does not open on its home screen, and instead opens on the default list of contacts, it felt important to set that up first. Some basic app state management is also setup for managing contact lists across the app. Boilerplate visuals are setup for two of the screens. Improved fidelity will come later. <img width="855" alt="Screenshot 2025-01-27 at 12 09 57 PM" src="https://github.com/user-attachments/assets/de091c7c-11ac-4350-9362-61b9c26b2aca" /> <img width="841" alt="Screenshot 2025-01-27 at 12 04 07 PM" src="https://github.com/user-attachments/assets/fe822b06-a432-44cf-ab24-f3e7a88955e5" />
This commit is contained in:
9
rolodex/lib/data/contact.dart
Normal file
9
rolodex/lib/data/contact.dart
Normal file
@@ -0,0 +1,9 @@
|
||||
// Copyright 2018 The Flutter team. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
class Contact {
|
||||
Contact({required this.id});
|
||||
|
||||
final int id;
|
||||
}
|
||||
44
rolodex/lib/data/contact_list.dart
Normal file
44
rolodex/lib/data/contact_list.dart
Normal file
@@ -0,0 +1,44 @@
|
||||
// Copyright 2018 The Flutter team. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
import 'package:flutter/cupertino.dart';
|
||||
|
||||
import 'contact.dart';
|
||||
|
||||
class ContactList {
|
||||
ContactList({
|
||||
required this.id,
|
||||
required this.label,
|
||||
this.permanent = false,
|
||||
String? title,
|
||||
}) : title = title ?? label;
|
||||
|
||||
final int id;
|
||||
|
||||
final bool permanent;
|
||||
|
||||
final String label;
|
||||
|
||||
final String title;
|
||||
|
||||
final List<Contact> contacts = [];
|
||||
}
|
||||
|
||||
class ContactListsModel extends ChangeNotifier {
|
||||
final List<ContactList> _lists = generateSeedData();
|
||||
|
||||
List<ContactList> get lists => _lists;
|
||||
|
||||
ContactList findContactList(int id) {
|
||||
return lists[id];
|
||||
}
|
||||
}
|
||||
|
||||
List<ContactList> generateSeedData() {
|
||||
return [
|
||||
ContactList(id: 0, permanent: true, label: 'All iPhone', title: 'iPhone'),
|
||||
ContactList(id: 1, label: 'Friends'),
|
||||
ContactList(id: 2, label: 'Work'),
|
||||
];
|
||||
}
|
||||
53
rolodex/lib/main.dart
Normal file
53
rolodex/lib/main.dart
Normal file
@@ -0,0 +1,53 @@
|
||||
// Copyright 2018 The Flutter team. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
|
||||
import 'data/contact_list.dart';
|
||||
import 'screens/contacts.dart';
|
||||
import 'screens/lists.dart';
|
||||
|
||||
void main() {
|
||||
runApp(const RolodexApp());
|
||||
}
|
||||
|
||||
class RolodexApp extends StatelessWidget {
|
||||
const RolodexApp({super.key});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return ChangeNotifierProvider(
|
||||
create: (context) => ContactListsModel(),
|
||||
child: CupertinoApp(
|
||||
title: 'Rolodex',
|
||||
initialRoute: '/contacts',
|
||||
onGenerateInitialRoutes: (initialRoute) {
|
||||
return [
|
||||
CupertinoPageRoute(
|
||||
title: 'Lists',
|
||||
builder: (BuildContext context) {
|
||||
return ListsPage();
|
||||
},
|
||||
),
|
||||
CupertinoPageRoute(
|
||||
builder: (BuildContext context) {
|
||||
return ContactListsPage(listId: 0);
|
||||
},
|
||||
),
|
||||
];
|
||||
},
|
||||
onUnknownRoute: (RouteSettings settings) {
|
||||
return CupertinoPageRoute(
|
||||
builder: (BuildContext context) {
|
||||
return const CupertinoPageScaffold(
|
||||
child: Center(child: Text('Unknown Route')),
|
||||
);
|
||||
},
|
||||
);
|
||||
},
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
37
rolodex/lib/screens/contacts.dart
Normal file
37
rolodex/lib/screens/contacts.dart
Normal file
@@ -0,0 +1,37 @@
|
||||
// Copyright 2018 The Flutter team. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
import 'package:rolodex/data/contact_list.dart';
|
||||
|
||||
class ContactListsPage extends StatelessWidget {
|
||||
const ContactListsPage({super.key, required this.listId});
|
||||
|
||||
final int listId;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return CupertinoPageScaffold(
|
||||
child: Consumer<ContactListsModel>(
|
||||
builder: (context, contactLists, child) {
|
||||
final ContactList contacts = contactLists.findContactList(listId);
|
||||
return CustomScrollView(
|
||||
slivers: [
|
||||
CupertinoSliverNavigationBar(
|
||||
automaticallyImplyLeading: true,
|
||||
largeTitle: Text(contacts.title),
|
||||
trailing: CupertinoButton(
|
||||
onPressed: () {},
|
||||
child: Icon(CupertinoIcons.add),
|
||||
),
|
||||
),
|
||||
SliverFillRemaining(child: Center(child: Text('Contacts page'))),
|
||||
],
|
||||
);
|
||||
},
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
67
rolodex/lib/screens/lists.dart
Normal file
67
rolodex/lib/screens/lists.dart
Normal file
@@ -0,0 +1,67 @@
|
||||
// Copyright 2018 The Flutter team. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
import 'package:rolodex/data/contact_list.dart';
|
||||
import 'contacts.dart';
|
||||
|
||||
class ListsPage extends StatelessWidget {
|
||||
const ListsPage({super.key});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return CupertinoPageScaffold(
|
||||
backgroundColor: CupertinoColors.extraLightBackgroundGray,
|
||||
child: CustomScrollView(
|
||||
slivers: [
|
||||
CupertinoSliverNavigationBar(
|
||||
leading: CupertinoButton(
|
||||
padding: EdgeInsets.zero,
|
||||
onPressed: () {},
|
||||
child: Text('Edit'),
|
||||
),
|
||||
largeTitle: Text('Lists'),
|
||||
trailing: CupertinoButton(
|
||||
padding: EdgeInsets.zero,
|
||||
onPressed: () {},
|
||||
child: Text('Add List'),
|
||||
),
|
||||
),
|
||||
SliverFillRemaining(
|
||||
child: Consumer<ContactListsModel>(
|
||||
builder: (context, contactLists, child) {
|
||||
return CupertinoListSection.insetGrouped(
|
||||
header: Text('iPhone'),
|
||||
children: [
|
||||
for (ContactList contactList in contactLists.lists)
|
||||
CupertinoListTile(
|
||||
leading: Icon(
|
||||
contactList.id == 0
|
||||
? CupertinoIcons.group
|
||||
: CupertinoIcons.person_2,
|
||||
),
|
||||
title: Text(contactList.label),
|
||||
onTap:
|
||||
() => Navigator.of(context).push(
|
||||
CupertinoPageRoute(
|
||||
title: contactList.title,
|
||||
builder: (BuildContext context) {
|
||||
return ContactListsPage(
|
||||
listId: contactList.id,
|
||||
);
|
||||
},
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
);
|
||||
},
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user