Skip to content

Instantly share code, notes, and snippets.

@Andrious
Last active March 31, 2024 06:02
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save Andrious/7ac920dc3077d080dc6ba36d9e66cbe3 to your computer and use it in GitHub Desktop.
Save Andrious/7ac920dc3077d080dc6ba36d9e66cbe3 to your computer and use it in GitHub Desktop.
Write Your First App example using both the Marterial design or the Cupertino design.
import 'dart:io' show Platform;
import 'package:flutter/foundation.dart' show kIsWeb;
import 'package:english_words/english_words.dart';
import 'package:flutter/material.dart';
import 'package:flutter/cupertino.dart';
void main() => runApp(MyApp(
switchUI: true,
));
class MyApp extends StatelessWidget {
MyApp({
this.key,
this.android = false,
this.iOS = false,
this.switchUI = false,
}) {
_useMaterial = android;
_useCupertino = iOS;
_switchUI = switchUI;
}
final Key key;
final bool android;
final bool iOS;
final bool switchUI;
static bool _useMaterial;
static bool _useCupertino;
static bool _switchUI;
@override
Widget build(BuildContext context) {
String title = 'Startup Name Generator';
Widget home = RandomWords(key: key);
if (useCupertino) {
return CupertinoApp(
title: title,
home: home,
);
} else {
return MaterialApp(
title: title,
home: home,
);
}
}
// Use Material UI when explicitly specified or even when running in iOS
static bool get useMaterial =>
(_useMaterial && !_useCupertino) ||
(Platform.isAndroid && !_switchUI && !_useCupertino) ||
(Platform.isIOS && _switchUI) ||
(kIsWeb && !_switchUI);
// Use Cupertino UI when explicitly specified or even when running in Android
static bool get useCupertino =>
(_useCupertino && !_useMaterial) ||
(Platform.isIOS && !_switchUI && !_useMaterial) ||
(Platform.isAndroid && _switchUI) ||
(kIsWeb && _switchUI);
}
class RandomWords extends StatefulWidget {
RandomWords({
Key key,
this.useMaterial = false,
this.useCupertino = false,
this.switchUI = false,
}) : super(key: key);
final bool useMaterial;
final bool useCupertino;
final bool switchUI;
@override
State createState() =>
MyApp.useMaterial ? RandomWordsAndroid() : RandomWordsApple();
}
class RandomWordsAndroid extends State<RandomWords> {
RandomWordsAndroid() {
wordPair = _WordPair(this);
}
_WordPair wordPair;
final _biggerFont = const TextStyle(fontSize: 18.0);
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Startup Name Generator'),
),
body: ListView.builder(
padding: const EdgeInsets.all(16.0),
itemBuilder: (context, i) {
if (i.isOdd) return Divider();
wordPair.build(i);
return ListTile(
title: Text(
wordPair.current.asPascalCase,
style: _biggerFont,
),
trailing: wordPair.icon,
onTap: () {
wordPair.onTap(i);
},
);
}),
);
}
}
class RandomWordsApple extends State<RandomWords> {
RandomWordsApple() {
wordPair = _WordPair(this);
}
_WordPair wordPair;
@override
Widget build(BuildContext context) {
return CupertinoPageScaffold(
child: CustomScrollView(
slivers: <Widget>[
const CupertinoSliverNavigationBar(
largeTitle: Text('Startup Name Generator'),
),
SliverSafeArea(
top: false,
minimum: const EdgeInsets.only(top: 8),
sliver: SliverList(
delegate: SliverChildBuilderDelegate(
(context, i) {
if (i.isOdd) return Divider();
wordPair.build(i);
return CupertinoListTile(
title: wordPair.current.asPascalCase,
trailing: wordPair.icon,
onTap: () {
wordPair.onTap(i);
},
);
},
),
),
)
],
),
);
}
}
class _WordPair {
_WordPair(this.state);
final State state;
final suggestions = <WordPair>[];
final Set<WordPair> saved = <WordPair>{};
int index;
void build(int i) {
index = i ~/ 2;
if (index >= suggestions.length) {
suggestions.addAll(generateWordPairs().take(10));
}
}
WordPair get current => suggestions[index];
Icon get icon {
bool alreadySaved = saved.contains(suggestions[index]);
return Icon(
alreadySaved ? Icons.favorite : Icons.favorite_border,
color: alreadySaved ? Colors.red : null,
);
}
void onTap(int i) => state.setState(() {
int index = i ~/ 2;
WordPair pair = suggestions[index];
if (pair == null) return;
if (saved.contains(suggestions[index])) {
saved.remove(pair);
} else {
saved.add(pair);
}
});
}
/// Cupertino needs a ListTile equivalent
/// https://github.com/flutter/flutter/issues/50668#issuecomment-593060684
class CupertinoListTile extends StatefulWidget {
const CupertinoListTile({
Key key,
this.leading,
this.title,
this.subtitle,
this.trailing,
this.onTap,
}) : super(key: key);
final Widget leading;
final String title;
final String subtitle;
final Widget trailing;
final Function onTap;
@override
_StatefulStateCupertino createState() => _StatefulStateCupertino();
}
class _StatefulStateCupertino extends State<CupertinoListTile> {
@override
Widget build(BuildContext context) {
Widget leading;
if (widget.leading == null) {
leading = const SizedBox();
} else {
leading = widget.leading;
}
Widget trailing;
if (widget.trailing == null) {
trailing = const SizedBox();
} else {
trailing = widget.trailing;
}
return GestureDetector(
onTap: () {
if (widget.onTap != null) widget.onTap();
},
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
Row(
children: <Widget>[
leading,
SizedBox(width: 10),
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: columnChildren(context),
),
],
),
trailing,
],
),
);
}
List<Widget> columnChildren(BuildContext context) {
List<Widget> children = List();
bool isDark = MediaQuery.of(context).platformBrightness == Brightness.dark;
Widget title = widget.title != null
? Text(
widget.title,
style: TextStyle(
fontSize: 25.0, color: isDark ? Colors.white : Colors.black),
)
: const SizedBox();
children.add(title);
if (widget.subtitle != null)
children.add(Text(widget.subtitle,
style: TextStyle(color: CupertinoColors.systemGrey)));
return children;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment