Skip to content

Instantly share code, notes, and snippets.

@agnamc9
Created September 25, 2020 11:47
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
Star You must be signed in to star a gist
Save agnamc9/729fa8289cf41956e982c4a3b6dfefc9 to your computer and use it in GitHub Desktop.
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.generate(6, (index) => "Article ${index + 1}");
// 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;
// 'pageController.page' is not available immediatly. Access will cause a crash
// if it is true, we'll access to 'pageController.page'
bool isPageControllerLoaded = false;
AnimationController animationController;
int itemsLenght;
@override
void initState() {
super.initState();
// store number of item
itemsLenght = articles.length;
// initialization with current page
pageController = PageController(
initialPage: currentPage,
);
pageController.addListener(() {
// if this block work, we'll update it value to true an access to 'pageController.page'
if (!isPageControllerLoaded) isPageControllerLoaded = true;
});
}
@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(
// do not define 'itemCount'
scrollDirection: Axis.horizontal,
physics: PageScrollPhysics(),
controller: pageController,
itemBuilder: (context, index) {
return AnimatedBuilder(
animation: pageController,
child: _buildItem(index % (itemsLenght ~/ 2)),
builder: (context, child) {
var pageValue =
isPageControllerLoaded ? pageController.page : 0;
var value = (pageValue - index).clamp(0, 1);
// After some observations I noticed than from the second item
// 'value' of the previous item goes to 1.0
// 'value' of the current and next items goes to 0.0
print('index = $index value $value');
// 'offset' should be equal to 'itemOffset' at the end of list scrolling
var offset = itemOffset * (1 - value);
return Container(
height: 200,
width: screenWidth - offset,
padding: EdgeInsets.all(4.0),
child: child,
);
},
);
},
),
)
],
),
),
);
}
// list item widget
Widget _buildItem(index) {
return Column(
children: [
Column(
children: [
Row(
children: [
Placeholder(
fallbackWidth: 30,
fallbackHeight: 30,
),
SizedBox(
width: 10,
),
Expanded(
child: Text(articles[index % itemsLenght * 2]),
),
],
),
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(articles[index % itemsLenght * 2 + 1]),
),
],
),
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