Created
September 25, 2020 02:08
-
-
Save agnamc9/62950d46b1256c592d47cab1104bebc0 to your computer and use it in GitHub Desktop.
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'; | |
void main() { | |
runApp(MyApp()); | |
} | |
class MyApp extends StatelessWidget { | |
// This widget is the root of your application. | |
@override | |
Widget build(BuildContext context) { | |
return MaterialApp( | |
title: 'Flutter Demo', | |
theme: ThemeData( | |
primarySwatch: Colors.blue, | |
visualDensity: VisualDensity.adaptivePlatformDensity, | |
), | |
home: ListSnapPage(), | |
); | |
} | |
} | |
class ListSnapPage extends StatefulWidget { | |
@override | |
_ListSnapPageState createState() => _ListSnapPageState(); | |
} | |
class _ListSnapPageState extends State<ListSnapPage> { | |
// create a list of 6 items | |
List<String> articles = List.filled(6, ""); | |
// for listening scroll position | |
PageController pageController; | |
// visible item position | |
int currentPage = 0; | |
// substraction value for seeing a little bit next item (right) | |
int itemOffset = 50; | |
@override | |
void initState() { | |
super.initState(); | |
pageController = PageController(initialPage: 0); | |
pageController.addListener(listenListViewScrolling); | |
} | |
/// Listening page scrolling... | |
/// I noticed decimal value of 'pageController.page' is not null when the list is scrolling | |
/// I compare 'page' value to its rounded version to verify if the list is moving | |
/// If the list still moves, we'll get for example page = 3.6 and rounded(page) = 4.0. It'll return false | |
/// Otherwise we'll get page = 4.0 and rounded(page) = 4.0 too. At this case, I update 'currentPage' value | |
listenListViewScrolling() { | |
var page = pageController.page; | |
if (page == page.roundToDouble()) { | |
setState(() { | |
currentPage = page.toInt(); | |
}); | |
} | |
} | |
@override | |
Widget build(BuildContext context) { | |
double screenWidth = MediaQuery.of(context).size.width; | |
return Scaffold( | |
body: SafeArea( | |
child: Column( | |
children: [ | |
Container( | |
height: 200, | |
child: ListView.builder( | |
itemCount: articles.length, | |
scrollDirection: Axis.horizontal, | |
physics: PageScrollPhysics(), | |
controller: pageController, | |
itemBuilder: (context, index) { | |
return Container( | |
height: 200, | |
// make substraction only when element at index is visible (in center i.e currentPage == index) | |
width: screenWidth - | |
itemOffset * (currentPage == index ? 1 : 0), | |
padding: EdgeInsets.all(4.0), | |
child: _buildItem(index)); | |
}, | |
), | |
) | |
], | |
), | |
), | |
); | |
} | |
// list item | |
Widget _buildItem(index) { | |
return Column( | |
children: [ | |
Column( | |
children: [ | |
Row( | |
children: [ | |
Placeholder( | |
fallbackWidth: 30, | |
fallbackHeight: 30, | |
), | |
SizedBox( | |
width: 10, | |
), | |
Expanded(child: Text('Article ${index * 2 + 1}')), | |
], | |
), | |
SizedBox( | |
height: 10, | |
), | |
Divider( | |
height: 1, | |
color: Colors.black, | |
) | |
], | |
), | |
SizedBox( | |
height: 10, | |
), | |
Column( | |
children: [ | |
Row( | |
children: [ | |
Placeholder( | |
fallbackWidth: 30, | |
fallbackHeight: 30, | |
), | |
SizedBox( | |
width: 10, | |
), | |
Expanded(child: Text('Article ${index * 2 + 2}')), | |
], | |
), | |
SizedBox( | |
height: 10, | |
), | |
Divider( | |
height: 1, | |
color: Colors.black, | |
) | |
], | |
), | |
], | |
); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment