I need help to create scrollable body:
my screen
This is how my structure of body looks: build()
body: Padding(
padding: const EdgeInsets.all(30.0),
child: DragAndDropLists(
children: _contents,
onItemReorder: _onItemReorder,
onListReorder: _onListReorder,
axis: Axis.horizontal,
listWidth: 300,
listDraggingWidth: 300,
listPadding: EdgeInsets.all(20.0),
itemDivider: const Divider(
thickness: 4,
height: 10,
color: lightBlue,
),
itemDecorationWhileDragging: BoxDecoration(
color: Colors.white,
boxShadow: [
BoxShadow(
color: const Color(0xff004269).withOpacity(0.5),
spreadRadius: 2,
blurRadius: 3,
offset: const Offset(0, 0), // changes position of shadow
),
],
),
listInnerDecoration: BoxDecoration(
color: Theme.of(context).canvasColor,
borderRadius: BorderRadius.all(Radius.circular(5)),
),
lastItemTargetHeight: 2,
addLastItemTargetHeightToTop: true,
lastListTargetSize: 40,
),
),
I tried already ListView, SingleChildScrollView, Column
I don't know why but it's doesn't work
Maybe somebody has an idea what I can change to see scrollbar and can scroll it horizontally
Thank you
You seem to be using a bit of complex layout, but a simplified version would look something like this:
You can set scrollDirection property of ListView to Axis.horizontal and for scrollbar you can wrap ListView inside Scrollbar.
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatefulWidget {
MyApp({Key? key}) : super(key: key);
#override
State<MyApp> createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
final ScrollController _scrollController = ScrollController();
final List<int> _items = List<int>.generate(100, (int index) => index);
#override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
body: SizedBox(
height: 150,
child: Scrollbar(
isAlwaysShown: true,
controller: _scrollController,
child: ReorderableListView.builder(
scrollDirection: Axis.horizontal,
scrollController: _scrollController,
itemBuilder: buildItem,
itemCount: _items.length,
onReorder: (int oldIndex, int newIndex) {
setState(() {
if (oldIndex < newIndex) {
newIndex -= 1;
}
final int item = _items.removeAt(oldIndex);
_items.insert(newIndex, item);
});
},
),
),
),
));
}
Widget buildItem(context, index) {
return Container(
key: Key('$index'),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(10),
color: Colors.green[200],
),
margin: const EdgeInsets.all(8.0),
height: 100,
width: 100,
child: Center(child: Text('${_items[index]}')),
);
}
}
Ignore the handles, they only appear on desktop, drag and drop works on mobile devices.
Try wrap Padding in your Scaffold with SingleChildScrollView
SingleChildScrollView(
scrollDirection: Axis.horizontal,
child: Padding(),
)
Other option that you can use is GridView, and ListView.
Related
I want to change screens with custom tab bar,i want when i click Allshoes(the page of all shoes should display) then jordan and the rest, i have tried so many ways but it is not working for me. please assit me.
The image
I want to change screens with custom tab bar,i want when i click Allshoes(the page of all shoes should display) then jordan and the rest, i have tried so many ways but it is not working for me. please assit me.
`class MyTabBar extends StatefulWidget {
const MyTabBar({Key? key}) : super(key: key);
#override
State<MyTabBar> createState() => _MyTabBarState();
}
class _MyTabBarState extends State<MyTabBar>
with SingleTickerProviderStateMixin{
int _isSelectedIndex = 0;
late TabController _tabController;
#override
void initState() {
super.initState();
_tabController = TabController(vsync: this, length: 6);
}
#override
void dispose() {
_tabController.dispose();
super.dispose();
}
List<Widget> pageList = [
const AllShoesPage(),
const JordanPage(),
const BasketBallPage(),
const TennisPage(),
const WalkingPage(),
const SoccerPage()
];
#override
Widget build(BuildContext context) {
return Column(
children: [
SizedBox(
height: 60.0,
width: double.infinity,
child: TabBar(
controller: _tabController,
tabs: [ListView.builder(
physics: const BouncingScrollPhysics(),
itemCount: tabBarItems.length,
scrollDirection: Axis.horizontal,
itemBuilder: (BuildContext context, index) {
return Column(
children: [
GestureDetector(
onTap: () => setState(() =>_isSelectedIndex = index),
child: Container(
margin: const EdgeInsets.all(5.0),
height: 45,
width: MediaQuery.of(context).size.width / 5,
decoration: BoxDecoration(
color: _isSelectedIndex == index
? Appcolors.primaryColor
: Appcolors.whiteColor,
borderRadius: BorderRadius.circular(10.0),
),
child: Center(
child: Text(
tabBarItems[index],
style: GoogleFonts.poppins(
color: _isSelectedIndex == index
? Appcolors.whiteColor
: Appcolors.darkGreyColor),
),
),
)
),
Visibility(
visible: _isSelectedIndex == index,
child: Container(
width: 5,
height: 5,
decoration: const BoxDecoration(
color: Appcolors.primaryColor,
shape: BoxShape.circle),
),
)
],
);
},
)]
),
),
TabBarView(
controller: _tabController,
children: pageList)
],
);
}
}
`
Here, tabs require list of Widgets but you provide only one Widget which is listView.builder, instead try this
tabs: List.generate(tabBarItems.length, (index) => MyWidget())
Since you are already using TabBar so you don't need to use GestureDetector(), also if you don't want horizontal scrolling effect make isScrollable: flase,
also wrap TabBarView with Expanded Widget like this
Expanded(child: TabBarView())
I am trying find a way for the user to Scroll Parent Widget when Child Widgets have been scrolled to the top or bottom, whilst maintaining the scroll velocity / scroll momentum / scroll physics / user experience.
A good demonstration of what I'm trying to achieve (albeit without BouncingScrollPhysics): https://imgur.com/WJRCbk3
Taken from: Flutter: Continue scrolling in top Listview when reaching bottom of nested Listview
I appreciate lots of similar questions to this have been asked already, with answers relating to NotificationListener, which I have tried. However this method does not maintain the scroll velocity / scroll momentum / scroll physics / user experience, so leads to a poor quality user experience. Flutter: Continue scrolling in top Listview when reaching bottom of nested Listview looks to use a different method that might achieve the desired results, but I'm unable to get it to work correctly / with allowed operation conditions).
It seems odd there is not yet an answer to fully satisfies the desired functionality as it is very common on websites. It's clear by the number of questions on this topic, a full solution would be really appreciated.
Best Q&As so far:
Flutter : ListView : Scroll parent ListView when child ListView reach bottom - ClampingScrollPhysics not working in sized container
Is there any way to scroll parent listview when the child listview reached end in flutter?
Flutter: Continue scrolling in top Listview when reaching bottom of nested Listview
Other similar Q&As:
How to automatically start scrolling a parent scrollable widget when the child scrollable reaches the top in flutter
Flutter Nested list scroll parent when reach to end/start of inner list
I have created some basic code that can be used to test / demonstrate solutions that 'everyone' should be able to understand easily:
import 'package:flutter/material.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: const MyHomePage(title: 'Flutter Demo Home Page'),
);
}
}
class MyHomePage extends StatefulWidget {
const MyHomePage({Key? key, required this.title}) : super(key: key);
final String title;
#override
State<MyHomePage> createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
final ScrollController _textAController = ScrollController();
final ScrollController _textBController = ScrollController();
final ScrollController _pageController = ScrollController();
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: ListView(
controller: _pageController,
children: [
Container(
height: 200,
color: Colors.green,
),
Container(
height: 200,
color: Colors.red,
),
Padding(
padding: const EdgeInsets.only(bottom: 8.0),
child: ConstrainedBox(
constraints: const BoxConstraints(maxHeight: 200),
child: SingleChildScrollView(
padding: const EdgeInsets.only(right: 15),
controller: _textAController,
physics: const ClampingScrollPhysics(),
child: Column(
children: [
const Text(
'Scrollable Child 1',
softWrap: true,
textAlign: TextAlign.center,
),
Container(
color: Colors.amber,
height: 600,
)
],
),
),
),
),
Container(
height: 10,
color: Colors.purple,
),
Padding(
padding: const EdgeInsets.only(top: 8.0),
child: ConstrainedBox(
constraints: const BoxConstraints(maxHeight: 200),
child: SingleChildScrollView(
controller: _textBController,
physics: const ClampingScrollPhysics(),
padding: const EdgeInsets.only(right: 15),
child: Column(
children: [
const Text(
'Scrollable Child 2',
softWrap: true,
textAlign: TextAlign.center,
),
ListView.separated(
physics: const NeverScrollableScrollPhysics(),
separatorBuilder: (BuildContext context, index) {
return Container(
height: 12,
width: 50,
color: Colors.grey,
);
},
shrinkWrap: true,
padding: const EdgeInsets.fromLTRB(0, 0, 0, 0),
itemCount: 5,
itemBuilder: (BuildContext context, int index) {
return Container(
height: 60,
color: Colors.black,
);
},
),
],
),
),
),
),
Container(
height: 100,
color: Colors.blue,
),
],
),
);
}
}
I was having the same problem until I came across your post and your links to some of the other posts trying to solve the same problem. So thanks for pointing me in the right direction. The key to it is using the velocity data provided by some of the scroll events you can listen to with the NotificationListener:
My solution is a little hackier than i'd ideally like, but the behavior is what you're after I believe.
import 'package:flutter/material.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: const MyHomePage(title: 'Flutter Demo Home Page'),
);
}
}
class MyHomePage extends StatefulWidget {
const MyHomePage({Key? key, required this.title}) : super(key: key);
final String title;
#override
State<MyHomePage> createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
final ScrollController _textAController = ScrollController();
final ScrollController _textBController = ScrollController();
final ScrollController _pageController = ScrollController();
bool _scrolling = false;
getMinMaxPosition(double tryScrollTo){
return
tryScrollTo < _pageController.position.minScrollExtent
? _pageController.position.minScrollExtent
: tryScrollTo > _pageController.position.maxScrollExtent
? _pageController.position.maxScrollExtent
: tryScrollTo;
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body:
NotificationListener(
onNotification: (ScrollNotification notification) {
//users finger is still on the screen
if(notification is OverscrollNotification && notification.velocity == 0){
var scrollTo = getMinMaxPosition(_pageController.position.pixels + (notification.overscroll));
_pageController.jumpTo(scrollTo);
}
//users finger left screen before limit of the listview was reached, but momentum takes it to the limit and beoyond
else if(notification is OverscrollNotification){
var yVelocity = notification.velocity;
_scrolling = true;//stops other notifiations overriding this scroll animation
var scrollTo = getMinMaxPosition(_pageController.position.pixels + (yVelocity/5));
_pageController.animateTo(scrollTo, duration: const Duration(milliseconds: 1000),curve: Curves.linearToEaseOut).then((value) => _scrolling = false);
}
//users finger left screen after the limit of teh list view was reached
else if(notification is ScrollEndNotification && notification.depth > 0 && !_scrolling){
var yVelocity = notification.dragDetails?.velocity.pixelsPerSecond.dy ?? 0;
var scrollTo = getMinMaxPosition(_pageController.position.pixels - (yVelocity/5));
var scrollToPractical = scrollTo < _pageController.position.minScrollExtent ? _pageController.position.minScrollExtent : scrollTo > _pageController.position.maxScrollExtent ? _pageController.position.maxScrollExtent : scrollTo;
_pageController.animateTo(scrollToPractical, duration: const Duration(milliseconds: 1000),curve: Curves.linearToEaseOut);
}
return true;
},
child: ListView(
controller: _pageController,
children: [
Container(
height: 200,
color: Colors.green,
),
Container(
height: 200,
color: Colors.red,
),
Padding(
padding: const EdgeInsets.only(bottom: 8.0),
child: ConstrainedBox(
constraints: const BoxConstraints(maxHeight: 200),
child: SingleChildScrollView(
padding: const EdgeInsets.only(right: 15),
controller: _textAController,
physics: const ClampingScrollPhysics(),
child: Column(
children: [
const Text(
'Scrollable Child 1',
softWrap: true,
textAlign: TextAlign.center,
),
Container(
color: Colors.amber,
height: 600,
)
],
),
),
),
),
Container(
height: 10,
color: Colors.purple,
),
Padding(
padding: const EdgeInsets.only(top: 8.0),
child: ConstrainedBox(
constraints: const BoxConstraints(maxHeight: 200),
child: SingleChildScrollView(
controller: _textBController,
physics: const ClampingScrollPhysics(),
padding: const EdgeInsets.only(right: 15),
child: Column(
children: [
const Text(
'Scrollable Child 2',
softWrap: true,
textAlign: TextAlign.center,
),
ListView.separated(
physics: const NeverScrollableScrollPhysics(),
separatorBuilder: (BuildContext context, index) {
return Container(
height: 12,
width: 50,
color: Colors.grey,
);
},
shrinkWrap: true,
padding: const EdgeInsets.fromLTRB(0, 0, 0, 0),
itemCount: 5,
itemBuilder: (BuildContext context, int index) {
return Container(
height: 60,
color: Colors.black,
);
},
),
],
),
),
),
),
Container(
height: 100,
color: Colors.blue,
),
],
)),
);
}
}
I've set up this Carousel using a PageView.builder. It displays 5 tiles at a time.
Once the user has swiped all the way over to the right & pulls on the last tile (see image)...I'd like to move onto the next set of 5 tiles in an array.
Is there an event handler for this? I've managed to set up a listener that can determine when the user has swiped to the last tile, but cannot figure out how to tell when they're pulling on this so it can be refreshed.
Appreciate any help I can get on this. Code below :)
import 'package:flutter/material.dart';
import 'package:smooth_page_indicator/smooth_page_indicator.dart';
class RecommendationPanel extends StatefulWidget {
#override
State<StatefulWidget> createState() {
return _buildRecommendationPanel();
}
}
class _buildRecommendationPanel extends State<RecommendationPanel> {
PageController _pageController = PageController();
#override
void initState() {
_pageController = PageController(viewportFraction: 1.0);
_pageController.addListener(_scrollListener);
super.initState();
}
void dispose() {
_pageController.dispose();
super.dispose();
}
_scrollListener() {
if (_pageController.offset >= _pageController.position.maxScrollExtent &&
!_pageController.position.outOfRange) {
setState(() {
//This is working in the sense that it tells when they're on the final tile
//I want it so knows when you drag to the right
print('Final tile');
//I could refresh the list and then just move everything back to #1 in the view...i.e. the last card [index 4] can now shift to 5
//_pageController.jumpToPage(0);
});
}
if (_pageController.offset <= _pageController.position.minScrollExtent &&
!_pageController.position.outOfRange) {
setState(() {
//Need to figure out how to work this - there's going to have to be another variable checking what place in the top N recommended array it is, and then adjust accordingly
print('Back to first tile');
//_pageController.jumpToPage(3);
});
}
}
#override
Widget build(BuildContext context) {
return Column(
mainAxisSize: MainAxisSize.min,
children: [
SizedBox(
//You may want to use aspect ratio here for tablet support
height: 270.0,
child: PageView.builder(
physics: const AlwaysScrollableScrollPhysics(),
itemCount: 5,
scrollDirection: Axis.horizontal,
controller: _pageController,
itemBuilder: (BuildContext context, int itemIndex) {
//I could potentially call something here to update the slider index
return _buildCarouselItem(context, itemIndex);
},
),
),
Container(
height: 30,
child: Center(
child: SmoothPageIndicator(
controller: _pageController,
count: 5,
effect: WormEffect(
spacing: 8.0,
dotHeight: 10,
dotWidth: 10,
activeDotColor: Colors.orange,
),
),
),
),
],
);
}
Widget _buildCarouselItem(BuildContext context, int itemIndex) {
List<String> labels = [
'Pub',
'Bar',
'Football Match',
'Nightclub',
'Book Festival',
'Six',
'Seven',
'Eight',
'Nine',
'Ten',
];
return Padding(
padding: EdgeInsets.symmetric(horizontal: 2.0),
child: Container(
height: double.infinity,
//color: Colors.red,
child: Column(
children: [
Container(
child: Card(
elevation: 2,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(10.0)),
child: Container(
// In here is where I should build each individual tile
decoration: BoxDecoration(
color: Colors.grey,
borderRadius: BorderRadius.all(Radius.circular(10.0)),
),
child: Container(
width: double.infinity,
height: 260,
child: Text(labels[itemIndex]),
),
),
),
),
],
),
),
);
}
Widget buildIndicator(BuildContext context, int itemIndex, int count) {
return AnimatedSmoothIndicator(
activeIndex: itemIndex,
count: count,
effect: WormEffect(
dotColor: Colors.grey,
activeDotColor: Colors.orange,
),
);
}
}
I have to implement a horizontal scroll list in flutter.I could do that and have included the code below(The code is still to be modified but the base of the code is good enough to put in the pictures and other such details)
But the problem is the minus bar below the horizontal scroll.I don't know what feature in flutter allows to do that.I search many things but other than radio boxes,check boxes, switches,etc I am not able to find any details of it.Please have a look at the screenshot of the app ,I have indicated the minus bar control in red.Home screen,the minus bar indicated in red
The code I have written:
#override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.black ,
body: Container(
margin: EdgeInsets.symmetric(vertical: 20.0),
height: 500,
child: ListView(
// This next line does the trick.
scrollDirection: Axis.horizontal,
shrinkWrap: true,
children: <Widget>[
Container(
width:400 ,
color: Colors.red,
),
Container(
width: 400.0,
color: Colors.blue,
),
Container(
width: 400.0,
color: Colors.green,
),
],
),
)
);
}
}
What you want to look for is not ListView but PageView here is a small code sample to try in DartPad and see how you could make your layout.
Basically I am using a PageController to change the current page by taping on certain widgets.
Code
import 'package:flutter/material.dart';
final Color darkBlue = Color.fromARGB(255, 18, 32, 47);
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
theme: ThemeData.dark().copyWith(scaffoldBackgroundColor: darkBlue),
debugShowCheckedModeBanner: false,
home: Scaffold(body: MyWidget()),
);
}
}
class MyWidget extends StatefulWidget {
#override
_MyWidgetState createState() => _MyWidgetState();
}
class _MyWidgetState extends State<MyWidget> {
final _items = [Colors.red, Colors.blue, Colors.yellow];
final _pageController = PageController();
int _currentPageNotifier = 0;
final double _indicatorWidth = 30;
Widget _buildPageView() {
return PageView.builder(
controller: _pageController,
itemCount: _items.length,
itemBuilder: (context, index) => Center(
child: FlutterLogo(
colors: _items[index],
size: 50,
),
),
onPageChanged: (int index) =>
setState(() => _currentPageNotifier = index),
);
}
Widget _buildIndicator() {
List<Widget> itemWidgets = [];
for (int index = 0; index < _items.length; index++) {
itemWidgets.add(GestureDetector(
onTap: () => _pageController.animateToPage(
index,
duration: Duration(milliseconds: 300),
curve: Curves.ease,
),
child: Container(
decoration: BoxDecoration(
color: _currentPageNotifier == index
? Colors.green
: Colors.grey,
borderRadius: BorderRadius.circular(9),
),
margin: EdgeInsets.only(right: 10),
width: _indicatorWidth,
height: 8,
),
));
}
return Positioned(
bottom: MediaQuery.of(context).size.height / 2 - 50,
left: MediaQuery.of(context).size.width / 2 -
_items.length * _indicatorWidth +
_items.length * 10,
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: itemWidgets,
),
);
}
#override
Widget build(BuildContext context) {
return Stack(
children: <Widget>[
_buildPageView(),
_buildIndicator(),
],
);
}
}
I am using PageView.builder to create pages.
PageView.builder(
itemCount: _pagesList.length,
itemBuilder: (BuildContext context, int index) {
return Container(
color: _pagesList[index],
);
}
)
What I currently have:
What I want:
i.e. I want to provide some Padding between pages (when they are being scrolled)
Reason: I will display Images in these pages, and since the Images will cover the full width of each page, it doesn't look nice when we scroll pages, since they are knitted together, like this:
How can I solve this?
PageController imagesController =
PageController(initialPage: 0, viewportFraction: 1.1);
PageView(
itemBuilder: (BuildContext context, int index) {
return Padding(
padding: EdgeInsets.only(left: 10, right: 10),
child: Container(
color: _pagesList[index],
),
);
}
),
If you want to add padding and still have your pages as wide as the screen:
I needed this exact same thing, also for displaying images. I wanted to add padding but at the same time have each image take up the entire screen width. I figured I could use Fahad Javed's technique and tweaking it a little bit by calculating the viewPortFraction based on the screen width and padding.
#override
Widget build(BuildContext context) {
double screenWidth = MediaQuery.of(context).size.width; // screen width
double screenPad = 16.0; // screen padding for swiping between pages
int _currentPosition = 0;
return PageView.builder(
scrollDirection: Axis.horizontal,
itemCount: data.length,
controller: PageController(
initialPage: _currentPosition,
viewportFraction:
1 + (screenPad * 2 / screenWidth)), // calculate viewPortFraction
onPageChanged: (int value) {
_currentPosition = value;
},
itemBuilder: (BuildContext context, int position) {
return Padding(
padding: EdgeInsets.only(left: screenPad, right: screenPad),
child: Text('YOUR PAGE CONTENT'),
);
},
);
}
This answer from on the question asked by Amon Kataria Github
final pageController = PageController(viewportFraction: 1.1);
PageView.builder(
controller: pageController,
itemCount: _pagesList.length,
itemBuilder: (BuildContext context, int index) {
return FractionallySizedBox(
widthFactor: 1 / pageController.viewportFraction,
child: Container(
color: _pagesList[index],
),
);
},
);
Thanks #mono0926
Best effort:
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',
home: Scaffold(
body: MyPageView()
)
);
}
}
class MyPageView extends StatefulWidget {
MyPageView({Key key}) : super(key: key);
_MyPageViewState createState() => _MyPageViewState();
}
class _MyPageViewState extends State<MyPageView> {
#override
Widget build(BuildContext context) {
return PageView(
children: <Widget>[
Container(
color: Colors.black,
child: Card(
color: Colors.red,
)
),
Container(
color: Colors.black,
child: Card(
color: Colors.blue,
),
),
Container(
color: Colors.black,
child: Card(
color: Colors.green,
),
),
],
);
}
}
You just need to add some padding around each page and the width of the page view must be at least the 'card width + the padding from both sides'. This worked for me:
class MyWidget extends StatelessWidget {
final _CARD_WIDTH = 220.0;
final PageController _controller = PageController(initialPage: 0);
#override
Widget build(BuildContext context) {
return Container(
height: _CARD_WIDTH,
width: _CARD_WIDTH + 32,
child: PageView(
scrollDirection: Axis.horizontal,
controller: _controller,
children: <Widget>[
_buildImageCard("1"),
_buildImageCard("2"),
_buildImageCard("3"),
],
),
);
}
Widget _buildImageCard(String text) {
return Padding(
padding: const EdgeInsets.only(left: 16.0, right: 16),
child: Container(
decoration: BoxDecoration(
color: Colors.blue,
borderRadius: BorderRadius.circular(15),
),
width: _CARD_WIDTH,
height: _CARD_WIDTH,
child: Center(
child: Text(text),
),
),
);
}
}