Created
April 13, 2018 22:04
-
-
Save manujbahl/7b218a6a07b0646c86836e3e56bf250e to your computer and use it in GitHub Desktop.
HorizontalFeaturedItems
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import 'package:flutter/material.dart'; | |
import 'package:flutter/rendering.dart'; | |
import 'package:meta/meta.dart'; | |
final colorBackground = const Color(0xFFF3F4F7); | |
void main() => runApp(new MyApp()); | |
class MyApp extends StatelessWidget { | |
@override | |
Widget build(BuildContext context) { | |
return new MaterialApp( | |
//debugShowCheckedModeBanner: false, | |
title: 'Test App', | |
home: new HomeScreen(), | |
); | |
} | |
} | |
class ScreenBackground extends StatelessWidget { | |
final Widget child; | |
ScreenBackground({@required this.child}); | |
@override | |
Widget build(BuildContext context) { | |
return new Material( | |
color: colorBackground, | |
child: child, | |
); | |
} | |
} | |
class HomeScreen extends StatelessWidget { | |
@override | |
Widget build(BuildContext context) { | |
return new ScreenBackground( | |
child: new SingleChildScrollView( | |
child: new Column( | |
crossAxisAlignment: CrossAxisAlignment.start, | |
children: <Widget>[ | |
new SizedBox(height: MediaQuery | |
.of(context) | |
.padding | |
.top), | |
new HorizontalFeaturedItems( | |
viewportFraction: (0.5), | |
aspectRatio: 1.5, | |
padding: const EdgeInsets.symmetric(vertical: 1.0, horizontal: 1.0), | |
itemCount: 5, | |
itemBuilder: this._buildFeaturedItems, | |
), | |
], | |
), | |
), | |
); | |
} | |
Widget _buildFeaturedItems(BuildContext context, int index) { | |
switch (index) { | |
case 0 : | |
return new FeaturedItem(title: 'Captain America', price: 'Chris Evans', | |
child: new Image.network("https://lumiere-a.akamaihd.net/v1/images/usa_avengers_chi_captainamerica_n_af12951d.png?region=0%2C0%2C300%2C300", fit: BoxFit.cover), | |
onTap: () => _featureCallback(index), | |
); | |
case 1: | |
return new FeaturedItem(title: 'Iron Man', price: 'Robert Downey Jr', | |
child: new Image.network("https://lumiere-a.akamaihd.net/v1/images/usa_avengers_chi_ironman_n_cf2a66b6.png?region=0%2C0%2C300%2C300", fit: BoxFit.cover), | |
onTap: () => _featureCallback(index), | |
); | |
case 2: | |
return new FeaturedItem(title: 'Thor', price: 'Chris Hemsworth', | |
child: new Image.network("https://lumiere-a.akamaihd.net/v1/images/open-uri20150422-20810-hwd89x_e15da04b.png?region=0%2C0%2C300%2C300", fit: BoxFit.cover), | |
onTap: () => _featureCallback(index), | |
); | |
case 3: | |
return new FeaturedItem(title: 'Incredible Hulk', price: 'Mark Ruffalo', | |
child: new Image.network("https://lumiere-a.akamaihd.net/v1/images/usa_avengers_chi_hulk_n_4d0875ae.png?region=0%2C0%2C300%2C300", fit: BoxFit.cover), | |
onTap: () => _featureCallback(index), | |
); | |
case 4: | |
return new FeaturedItem(title: 'Black Widow', price: 'Scarlett Johanson', | |
child: new Image.network("https://lumiere-a.akamaihd.net/v1/images/usa_avengers_chi_blackwidow_n_8346cbb6.png?region=0%2C0%2C300%2C300", fit: BoxFit.cover), | |
onTap: () => _featureCallback(index), | |
); | |
} | |
} | |
_featureCallback(int featureIndex) { | |
print("Feature #$featureIndex selected."); | |
} | |
} | |
class FeaturedItem extends StatelessWidget { | |
final String title; | |
final String price; | |
final VoidCallback onTap; | |
final Widget child; | |
FeaturedItem({ | |
@required this.title, | |
@required this.price, | |
this.onTap, | |
this.child, | |
}); | |
@override | |
Widget build(BuildContext context) { | |
return new Padding( | |
padding: const EdgeInsets.all(8.0), | |
child: new Column( | |
crossAxisAlignment: CrossAxisAlignment.stretch, | |
children: <Widget>[ | |
new Expanded( | |
child: new Material( | |
elevation: 12.0, | |
borderRadius: new BorderRadius.circular(10.0), | |
child: new Stack( | |
fit: StackFit.expand, | |
children: <Widget>[ | |
this.child, | |
new Material( | |
type: MaterialType.transparency, | |
child: new InkWell(onTap: this.onTap), | |
), | |
], | |
), | |
), | |
), | |
new Padding( | |
padding: const EdgeInsets.only(top: 16.0, bottom: 8.0), | |
child: new Text(this.title), | |
), | |
new Padding( | |
padding: const EdgeInsets.only(bottom: 12.0), | |
child: new Text(this.price, style: new TextStyle(fontWeight: FontWeight.bold)), | |
), | |
], | |
), | |
); | |
} | |
} | |
class HorizontalFeaturedItems extends StatelessWidget { | |
final int initialPage; | |
final double aspectRatio; | |
final double viewportFraction; | |
final EdgeInsetsGeometry padding; | |
final SliverChildDelegate childrenDelegate; | |
HorizontalFeaturedItems({ | |
Key key, | |
this.initialPage: 0, | |
this.aspectRatio: 1.0, | |
this.viewportFraction: 1.0, | |
this.padding, | |
@required IndexedWidgetBuilder itemBuilder, | |
int itemCount, | |
bool addAutomaticKeepAlives: true, | |
bool addRepaintBoundaries: true, | |
}) | |
: childrenDelegate = new SliverChildBuilderDelegate( | |
itemBuilder, | |
childCount: itemCount, | |
addAutomaticKeepAlives: addAutomaticKeepAlives, | |
addRepaintBoundaries: addRepaintBoundaries, | |
), | |
super(key: key); | |
@override | |
Widget build(BuildContext context) { | |
return new LayoutBuilder(builder: (BuildContext context, BoxConstraints constraints) { | |
final double itemWidth = (constraints.maxWidth - padding.horizontal) * this.viewportFraction; | |
final double itemHeight = (itemWidth * this.aspectRatio); | |
return new Container( | |
height: itemHeight, | |
child: new ListView.custom( | |
scrollDirection: Axis.horizontal, | |
controller: new PageController( | |
initialPage: this.initialPage, | |
viewportFraction: this.viewportFraction, | |
), | |
physics: const PageScrollPhysics(), | |
padding: this.padding, | |
itemExtent: itemWidth, | |
childrenDelegate: this.childrenDelegate, | |
), | |
); | |
}); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment