Skip to content

Instantly share code, notes, and snippets.

@manujbahl
Created April 13, 2018 22:04
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 manujbahl/7b218a6a07b0646c86836e3e56bf250e to your computer and use it in GitHub Desktop.
Save manujbahl/7b218a6a07b0646c86836e3e56bf250e to your computer and use it in GitHub Desktop.
HorizontalFeaturedItems
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