Skip to content

Instantly share code, notes, and snippets.

@rmarau
Last active August 30, 2018 15:58
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save rmarau/baa31a9c4032de388a2b7777c8bae27e to your computer and use it in GitHub Desktop.
Save rmarau/baa31a9c4032de388a2b7777c8bae27e to your computer and use it in GitHub Desktop.
import 'package:flutter/material.dart';
import 'package:http/http.dart';
import 'package:html/parser.dart' show parse;
import 'package:html/dom.dart' as dom;
void main() => runApp(new MyApp());
class MyApp extends StatelessWidget {
// This widget is the root of your application.
@override
Widget build(BuildContext context) {
return new MaterialApp(
title: 'Fun with Flags',
theme: new ThemeData(
primarySwatch: Colors.blue,
),
home: new MyHomePage(title: 'Fun with Flags'),
);
}
}
class MyHomePage extends StatefulWidget {
MyHomePage({Key key, this.title}) : super(key: key);
final String title;
@override
_MyHomePageState createState() => new _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
List<ListEntry> flags = List<ListEntry>();
@override
void initState() {
_loadFlags();
}
void _loadFlags(){
get("https://en.wikipedia.org/wiki/Gallery_of_sovereign_state_flags")
.then((Response response){
List<dom.Element> imgElems = parse(response.body)
.getElementsByClassName("thumbborder");
flags.clear();
imgElems.forEach((dom.Element elem){
String name = elem.attributes['alt']
.replaceAll( RegExp("Flag of (the)?"), "").trim();
String url = elem.attributes['src'].toString();
flags.add(ListEntry(name, url.startsWith("http") ?
url : "https:" + url));
});
setState(() { });
});
}
@override
Widget build(BuildContext context) {
return new Scaffold(
appBar: new AppBar(
title: new Text(widget.title),
),
body: new ListView.builder(
itemCount: flags.length,
itemBuilder: (BuildContext ctx, int index) {
return ExpandableCard(
defaultSize: 100.0,
expandedSize: 150.0,
header: new ListTile(
key: new ObjectKey(flags[index].name),
leading: Container(width: 100.0, height: 100.0,
child: new Image.network(flags[index].url, fit: BoxFit.contain,),
),
title: new Text(flags[index].name),
),
body: TextField(
decoration: InputDecoration(labelText: "Focus this > Scroll far down > Expand any"),
),
isExpanded: flags[index].isExpanded,
onTap: (){
flags[index].isExpanded = !flags[index].isExpanded;
//Tried to release the focus before expanding. No luck!
//FocusScope.of(context).requestFocus(new FocusNode());
setState(() {
/*flags = new List.from(flags);*/
});
},
);
}
),
floatingActionButton: new FloatingActionButton(
onPressed: _loadFlags,
tooltip: 'Reload',
child: new Icon(Icons.refresh),
),
);
}
}
class ListEntry{
final String name;
final String url;
bool isExpanded;
ListEntry(this.name, this.url, {this.isExpanded=false});
}
class ExpandableCard extends StatelessWidget {
final double defaultSize;
final double expandedSize;
final Widget header;
final Widget body;
final bool isExpanded;
final VoidCallback onTap;
ExpandableCard({ @required this.defaultSize, @required this.expandedSize,
@required this.header , @required this.body, this.isExpanded=false, this.onTap});
@override
Widget build(BuildContext context) {
return
new GestureDetector(
behavior: HitTestBehavior.opaque,
onTap: onTap,
child: new SafeArea(
top: false,
bottom: false,
child: new AnimatedContainer(
padding: const EdgeInsets.symmetric(horizontal: 4.0),
curve: Curves.fastOutSlowIn,
duration: kThemeAnimationDuration,
height: isExpanded ? expandedSize : defaultSize,
child:
new Card(
elevation: 1.0,
color: Colors.white,
child:
new Padding(
padding: new EdgeInsets.all(10.0),
child: new Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisSize: MainAxisSize.max,
children: <Widget>[
header,
new AnimatedCrossFade(
firstChild: new Container(height: 0.0),
secondChild: body,
firstCurve: const Interval(0.0, 0.6, curve: Curves.fastOutSlowIn),
secondCurve: const Interval(0.4, 1.0, curve: Curves.fastOutSlowIn),
sizeCurve: Curves.fastOutSlowIn,
crossFadeState: isExpanded ? CrossFadeState.showSecond : CrossFadeState.showFirst,
duration: kThemeAnimationDuration,
),
],
),
),
),
)
),
);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment