Skip to content

Instantly share code, notes, and snippets.

@PetreaLoredana
Last active August 8, 2021 13:52
Show Gist options
  • Star 3 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save PetreaLoredana/dde5c9cc3caa78c8fa6e12d43ca53021 to your computer and use it in GitHub Desktop.
Save PetreaLoredana/dde5c9cc3caa78c8fa6e12d43ca53021 to your computer and use it in GitHub Desktop.
This code generates a screen with a custom bidirectional and infinite scrollable PageView in Flutter. Replace your own assets names. More details can be found on Medium. https://medium.com/p/dfff43649c23/edit
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
void main() => runApp(CustomPageViewApp());
class CustomPageViewApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
SystemChrome.setPreferredOrientations([
DeviceOrientation.portraitUp,
DeviceOrientation.portraitDown,
]);
return MaterialApp(
title: 'Custom PageView',
home: CustomPageViewScreen(),
);
}
}
class CustomPageViewScreen extends StatefulWidget {
@override
_CustomPageViewScreenState createState() => new _CustomPageViewScreenState();
}
class _CustomPageViewScreenState extends State<CustomPageViewScreen> {
List interests = [
InterestsModel('Snowboarding', 'assets/ic_snowboarding_gray.png'),
InterestsModel('BMX', 'assets/ic_bike_gray.png'),
InterestsModel('Skateboarding', 'assets/ic_skateboarding_gray.png')
];
@override
Widget build(BuildContext context) {
return Scaffold(
body: Container(
color: Color.fromRGBO(36, 43, 47, 1),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
_buildTitle(),
_buildInterestsContent(),
_buildCheckIcon(),
_buildNextButton()
],
)),
);
}
Text _buildTitle() {
return Text(
"Choose your interests".toUpperCase(),
textAlign: TextAlign.center,
style: TextStyle(
color: Color.fromRGBO(243, 243, 243, 1),
fontSize: 19,
fontFamily: 'RadikalMedium'),
);
}
Stack _buildInterestsContent() {
return Stack(
children: <Widget>[
_buildInterestsPageView(),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
Image.asset('assets/bg_gradient_left.png'),
Image.asset('assets/bg_gradient_right.png'),
],
),
],
);
}
List selectedInterests = [];
PageController pageController =
PageController(viewportFraction: 0.45, initialPage: 4240);
Container _buildInterestsPageView() {
return Container(
height: 210,
child: PageView.builder(
itemBuilder: (context, int currentIdx) {
int crt = currentIdx;
if (crt > 2) {
if (crt % 3 == 0) {
crt = 0;
} else if ((crt + 1) % 3 == 0) {
crt = 2;
} else if ((crt - 1) % 3 == 0) {
crt = 1;
}
}
return Container(
margin: const EdgeInsets.only(top: 31.0),
child: _buildPageViewItem(interests[crt], crt),
);
},
controller: pageController,
),
);
}
GestureDetector _buildPageViewItem(InterestsModel data, int crt) {
bool active = selectedInterests.contains(crt);
final String backgroundAsset = active
? 'assets/bg_yellow_bordered.png'
: 'assets/bg_gray_bordered.png';
return GestureDetector(
onTap: () {
setState(() {
if (selectedInterests.contains(crt))
selectedInterests.remove(crt);
else {
selectedInterests.add(crt);
}
});
},
child: Column(
children: <Widget>[
Text(data.title.toUpperCase(),
style: TextStyle(
color: Color.fromRGBO(243, 243, 243, 1),
fontFamily: 'RadikalThin',
fontSize: 11.0,
)),
SizedBox(
height: 129,
width: 129,
child: Container(
margin: const EdgeInsets.only(top: 5),
decoration: BoxDecoration(
image: DecorationImage(image: AssetImage(backgroundAsset))),
child: Image.asset(data.imageAsset),
)),
],
),
);
}
Container _buildCheckIcon() {
String buttonAsset = selectedInterests.isEmpty
? 'assets/ic_check_gray.png'
: 'assets/ic_check_yellow_rounded.png';
return Container(
child: Image.asset(buttonAsset),
);
}
Container _buildNextButton() {
return Container(
alignment: Alignment.center,
margin: const EdgeInsets.only(left: 71, right: 71, top: 21),
child: SizedBox(
width: double.infinity,
height: 45,
child: RaisedButton(
child: Text(
"Next".toUpperCase(),
style: TextStyle(
color: Color.fromRGBO(40, 48, 52, 1),
fontFamily: 'RadikalMedium',
fontSize: 19),
),
color: Colors.white,
elevation: 4.0,
onPressed: () {},
),
),
);
}
}
class InterestsModel {
String imageAsset;
String title;
InterestsModel(this.title, this.imageAsset);
}
@lindembergandrade
Copy link

Hi, thanks for your code. May you push your project with your images? It has a beautiful design. Congratulations

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment