Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Horizontally scrollable cards with Snap effect in flutter

I want to create a list of cards scrolling horizontally with snap to fit effect when swiped either from left or right.

Each card has some spacing between them and fit to screen similar to below image

enter image description here

Apart from that these horizontally scrollable list elements should be contained inside a vertically scrollable list.

I all I am able to achieve is only displaying a list of horizontal scrolling cards after following example in flutter docs.

class SnapCarousel extends StatelessWidget {   @override   Widget build(BuildContext context) {     final title = 'Horizontal List';      return MaterialApp(       title: title,       home: Scaffold(         appBar: AppBar(           title: Text(title),         ),         body: Container(           margin: EdgeInsets.symmetric(vertical: 20.0),           height: 200.0,           child: ListView(             scrollDirection: Axis.horizontal,             children: <Widget>[               Container(                 width: 160.0,                 color: Colors.red,               ),               Container(                 width: 160.0,                 color: Colors.blue,               ),               Container(                 width: 160.0,                 color: Colors.green,               ),               Container(                 width: 160.0,                 color: Colors.yellow,               ),               Container(                 width: 160.0,                 color: Colors.orange,               ),             ],           ),         ),       ),     );   } } 
like image 603
WitVault Avatar asked Jul 31 '18 07:07

WitVault


People also ask

How do you make a horizontal scrollable list Flutter?

To scroll a Flutter ListView widget horizontally, set scrollDirection property of the ListView widget to Axis. horizontal. This arranges the items side by side horzontally. Following is the basic syntax to arrange the items horizontally in a ListView and scroll them horizontally.

How do I scroll GridView horizontally in Flutter?

You may want to change the scroll direction when the GridView is displayed in landscape mode. Setting scrollDirection to Axis. horizontal will do just that.


2 Answers

Use PageView and ListView:

import 'package:flutter/material.dart';  main() => runApp(MaterialApp(home: MyHomePage()));  class MyHomePage extends StatelessWidget {   @override   Widget build(BuildContext context) {     return Scaffold(       appBar: AppBar(         title: Text('Carousel in vertical scrollable'),       ),       body: ListView.builder(         padding: EdgeInsets.symmetric(vertical: 16.0),         itemBuilder: (BuildContext context, int index) {           if(index % 2 == 0) {             return _buildCarousel(context, index ~/ 2);           }           else {             return Divider();           }         },       ),     );   }    Widget _buildCarousel(BuildContext context, int carouselIndex) {     return Column(       mainAxisSize: MainAxisSize.min,       children: <Widget>[         Text('Carousel $carouselIndex'),         SizedBox(           // you may want to use an aspect ratio here for tablet support           height: 200.0,           child: PageView.builder(             // store this controller in a State to save the carousel scroll position             controller: PageController(viewportFraction: 0.8),             itemBuilder: (BuildContext context, int itemIndex) {               return _buildCarouselItem(context, carouselIndex, itemIndex);             },           ),         )       ],     );   }    Widget _buildCarouselItem(BuildContext context, int carouselIndex, int itemIndex) {     return Padding(       padding: EdgeInsets.symmetric(horizontal: 4.0),       child: Container(         decoration: BoxDecoration(           color: Colors.grey,           borderRadius: BorderRadius.all(Radius.circular(4.0)),         ),       ),     );   } } 
like image 124
boformer Avatar answered Oct 20 '22 21:10

boformer


Screenshot:

enter image description here


If you don't want to use any 3rd party packages, you can simply try this:

class _HomePageState extends State<HomePage> {   int _index = 0;    @override   Widget build(BuildContext context) {     return Scaffold(       appBar: AppBar(),       body: Center(         child: SizedBox(           height: 200, // card height           child: PageView.builder(             itemCount: 10,             controller: PageController(viewportFraction: 0.7),             onPageChanged: (int index) => setState(() => _index = index),             itemBuilder: (_, i) {               return Transform.scale(                 scale: i == _index ? 1 : 0.9,                 child: Card(                   elevation: 6,                   shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(20)),                   child: Center(                     child: Text(                       "Card ${i + 1}",                       style: TextStyle(fontSize: 32),                     ),                   ),                 ),               );             },           ),         ),       ),     );   } } 
like image 32
CopsOnRoad Avatar answered Oct 20 '22 20:10

CopsOnRoad