I tried to add carousel along with text. But As far I can only add image carousel, Have no idea on how to add text. Please help me. Totally new.
I expect the output to be like image on above and text on below, but both need to swipe at same time.
I have no idea where to add the text field. I made this carousel with a example in youtube. But no example for carousel images with text. I tried something manually, But it all doesn't ended much well.
Please help me fix it. Thank-you
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
home: MyHomePage(title: 'Slider'),
);
}
}
class MyHomePage extends StatefulWidget {
MyHomePage({Key key, this.title}) : super(key: key);
final String title;
#override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
PageController pageController;
//Images List
List<String> images = [
'',
];
#override
void initState() {
super.initState();
pageController = PageController(initialPage: 1, viewportFraction: 0.6);
}
#override
Widget build(BuildContext context) {
return Scaffold(
body: PageView.builder(
controller: pageController,
itemCount: images.length,
itemBuilder: (context, position) {
return imageSlider(position);
}
)
);
}
imageSlider(int index) {
return AnimatedBuilder(
animation: pageController,
builder: (context, widget) {
double value = 1;
if(pageController.position.haveDimensions){
value = pageController.page - index;
value = (1 - (value.abs() * 0.3.clamp(0.0, 1.0)));
}
return Center(
child: SizedBox(
height: Curves.easeInOut.transform(value) * 400.0,
width: Curves.easeInOut.transform(value) * 350.0,
child: widget,
),
);
},
child: Container(
margin: EdgeInsets.all(10.0),
child: Image.asset(images[index],fit: BoxFit.cover),
),
);
}
}
Use column instead of container, so just replace this:
child: Container(
margin: EdgeInsets.all(10.0),
child: Image.asset(images[index],fit: BoxFit.cover),
),
with this:
child: Column(
// To centralize the children.
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
// First child
Container(
margin: EdgeInsets.all(10.0),
child: Image.asset(images[index],fit: BoxFit.cover),
),
// Second child
Text(
'foo',
style: TextStyle(
// Add text's style here
),
),
]
),
OR instead of building your own carousal, you can use a ready to use one, e.g: carousel_slider or flutter_swiper
try this
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
Text(
heading,
style: TextStyle(
color: Colors.white,
fontSize: 20.0,
fontWeight: FontWeight.bold,
),
),
Padding(
padding: const EdgeInsets.all(10.0),
child: Text(
sub_heading,
style: TextStyle(
color: Colors.white,
fontSize: 15.0,
),
//textAlign: TextAlign.center,
),
),
],
),
PageView with Next and Previous Functionality
Step 1:- Add PageView widget
class _WalkThroughState extends State<WalkThrough> {
final GlobalKey<ScaffoldState> _scaffoldKey = new GlobalKey<ScaffoldState>();
var height = 0.0;
var width = 0.0;
int mCurrentIndex = -1;
List<Widget> pages=[PageOne(message: "Beauty Trends",),PageTwo(message: "Exclusive Offers",),PageThree(message: "Make your Kit",)];
PageController _controller = new PageController();
static const _kDuration = const Duration(milliseconds: 300);
static const _kCurve = Curves.ease;
#override
void initState() {
super.initState();
_controller = PageController();
}
#override
void dispose() {
_controller.dispose();
super.dispose();
}
#override
Widget build(BuildContext context) {
height = MediaQuery.of(context).size.height;
width = MediaQuery.of(context).size.width;
return Scaffold(
extendBodyBehindAppBar: true,
body: Stack(
children: [
Container(
height: height,
decoration: BoxDecoration(
gradient: LinearGradient(
begin: Alignment.topCenter,
end: Alignment.bottomCenter,
colors: [startColorBackground, endColorBackground])),
),
Column(
children: <Widget>[
Flexible(
child: Container(
child: PageIndicatorContainer(
key: _scaffoldKey,
child: PageView.builder(
controller: _controller,
onPageChanged: _onPageViewChange,
itemBuilder: (context, position) {
mCurrentIndex = position;
return pages[position];
},
itemCount: 3,
),
align: IndicatorAlign.bottom,
length: 3,
indicatorSpace: 10.0,
indicatorColor: Colors.white,
indicatorSelectorColor: Colors.black,
)),
),
Container(
child: Row(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
// ignore: invalid_use_of_protected_member
mCurrentIndex != 0 ?Padding(
padding: const EdgeInsets.only(left: 30.0, bottom: 30.0),
child: GestureDetector(
onTap: () {
_controller.previousPage(
duration: _kDuration, curve: _kCurve);
},
child: Text('Prev', style: TextStyle(fontSize: 20, fontWeight: FontWeight.w500),)),
) : Container(),
mCurrentIndex != 2 ? Padding(
padding: const EdgeInsets.only(right: 30.0, bottom: 30.0),
child: GestureDetector(
onTap: () {
_controller.nextPage(
duration: _kDuration, curve: _kCurve);
},
child: Text('Next', style: TextStyle(fontSize: 20, fontWeight: FontWeight.w500),)),
) : Container(),
],
),
),
],
),
],
),
);
}
_onPageViewChange(int page) {
/*print("Current Page: " + page.toString());
int previousPage = page;
if(page != 0) previousPage--;
else previousPage = 2;
print("Previous page: $previousPage");*/
setState(() {
mCurrentIndex = page;
print(mCurrentIndex);
});
}
}
Step 2:- Add Pages with data
Page 1
class PageOne extends StatelessWidget {
final String message;
var height = 0.0;
var width = 0.0;
PageOne({Key key, #required this.message}) : super(key: key);
#override
Widget build(BuildContext context) {
height = MediaQuery.of(context).size.height;
width = MediaQuery.of(context).size.width;
return Container(
height: height - 50,
child: Align(alignment: Alignment.center, child: Column(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: [
Container(
margin: EdgeInsets.only(top: 16.0),
child: Image(image: AssetImage("assets/images/banner_one.png"),)),
Container(
margin: EdgeInsets.only(bottom: 16.0),
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
Text(message, style: TextStyle(fontSize: 40, fontFamily: 'Playfair', fontWeight: FontWeight.bold),),
SizedBox(height: 30,),
Text("Lorem Ipsum is simply dummy text of the \n printing and typesetting industry.", textAlign: TextAlign.center, style: TextStyle(fontSize: 18),),
],
),
),
],
),),
);
}
}
Page 2
class PageTwo extends StatelessWidget {
final String message;
var height = 0.0;
var width = 0.0;
PageTwo({Key key, #required this.message}) : super(key: key);
#override
Widget build(BuildContext context) {
height = MediaQuery.of(context).size.height;
width = MediaQuery.of(context).size.width;
return Container(
child: Column(
children: [
Expanded(
flex: 2,
child: Container(
width: width,
child: Image(
width: double.infinity,
image: AssetImage("assets/images/banner_two.png"),
fit: BoxFit.cover,)),
),
Expanded(
flex: 1,
child: Container(
margin: EdgeInsets.only(top: 16),
child: Column(
children: [
SizedBox(
height: 40,
),
Text(message, style: TextStyle(fontSize: 40, fontFamily: 'Playfair', fontWeight: FontWeight.bold),),
SizedBox(height: 30,),
Text("Lorem Ipsum is simply dummy text of the \n printing and typesetting industry.", textAlign: TextAlign.center, style: TextStyle(fontSize: 18),),
],
),
),
),
],
),
);
}
}
Page 3
class PageThree extends StatelessWidget {
final String message;
var height = 0.0;
var width = 0.0;
PageThree({Key key, #required this.message}) : super(key: key);
#override
Widget build(BuildContext context) {
height = MediaQuery.of(context).size.height;
width = MediaQuery.of(context).size.width;
return Container(
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Expanded(
flex: 3,
child: Container(
width: width,
child: Image( width: double.infinity,
image: AssetImage("assets/images/banner_three.png"), fit: BoxFit.fill,)),
),
Expanded(
flex: 1,
child: Container(
child: Column(
children: [
Text(message, style: TextStyle(fontSize: 40, fontFamily: 'Playfair', fontWeight: FontWeight.bold),),
SizedBox(height: 30,),
Text("Lorem Ipsum is simply dummy text of the \n printing and typesetting industry.", textAlign: TextAlign.center, style: TextStyle(fontSize: 18),),
],
),
),
),
],
),
);
}
}
You can add N number of pages. Right now am adding 3 pages with data
Colors.dart
import 'package:flutter/material.dart';
const viewColor = Color(0xFFF5D9CE);
const textPinkColor = Color(0xFFF51678);
const buttonPinkColor = Color(0xFFF5147C);
const pinkColor = Color(0xFFF51479);
const pinkBackground = Color(0xFFF5C3C7);
const startColorBackground = Color(0xFFF5F4F2);
const endColorBackground = Color(0xFFF5EAE6);
This is complete working code with Image on top with text and dots. For this you need to use these two libraries:- " carousel_slider: ^4.1.1 ", "smooth_page_indicator: ^1.0.0+2", update them to the latest.
class MyItem {
String itemName;
String path;
MyItem(this.itemName, this.path);
}
class craouselImage extends StatefulWidget {
#override
_craouselImage createState() => _craouselImage();
}
class _craouselImage extends State<craouselImage> {
int activeIndex = 0;
List<MyItem> items = [
MyItem("item 1", 'assets/images/appiconlogo.png'),
MyItem("item 2", 'assets/images/Mockup4.png'),
];
#override
Widget build(BuildContext context) {
return Container(
child: Column(
children: [
CarouselSlider.builder(
itemCount: items.length,
options: CarouselOptions(
height: 400,
viewportFraction: 1,
autoPlay: true,
enlargeCenterPage: true,
enlargeStrategy: CenterPageEnlargeStrategy.height,
autoPlayInterval: const Duration(seconds: 1),
onPageChanged: (index, reason) {
setState(() {
activeIndex = index;
});
},
),
itemBuilder: (context, index, realIndex) {
final imgList = items[index];
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisSize: MainAxisSize.min,
children: [
Expanded(child: buildImage(imgList.path, index)),
const SizedBox(
height: 15,
),
buildText(imgList.itemName, index),
],
);
},
),
const SizedBox(
height: 22,
),
buildIndicator(),
const SizedBox(
height: 22,
),
//buildText(itemName, index),
// buildText(),
],
),
);
}
Widget buildImage(String imgList, int index) => Container(
margin: const EdgeInsets.symmetric(horizontal: 12),
color: Colors.transparent,
child: Align(
alignment: Alignment.center,
child: Image.asset(
imgList,
fit: BoxFit.cover,
),
),
);
buildIndicator() => AnimatedSmoothIndicator(
activeIndex: activeIndex,
count: items.length,
effect: const JumpingDotEffect(
dotColor: Colors.black,
dotHeight: 15,
dotWidth: 15,
activeDotColor: mRed),
);
buildText(String itemName, int index) => Align(
alignment: FractionalOffset.bottomCenter,
child: Text(
itemName,
style: const TextStyle(
fontWeight: FontWeight.w700, fontSize: 23, color: mRed),
));
}
Related
In my flutter application I want to create a timetable widget as below which will scroll horizontally and vertically with corresponding heading. The timetable should have 'Day' as horizontal heading and 'Period' as vertical heading. During horizontal scrolling the 'Period' header should freeze and horizontal 'Day' header should scroll with data. Similarly, during vertical scrolling the 'Day' header should freeze and vertical 'Period' header should scroll with data. How can I achieve a widget like that.Please help..
In Android we can obtain the above type of scrolling by extending HorizontalScrollView & VerticalScrollView.
You can archive this using nested listView widgets.
You can try this approach:
class TimeTableView extends StatefulWidget {
const TimeTableView({super.key});
#override
State<TimeTableView> createState() => _TimeTableViewState();
}
class _TimeTableViewState extends State<TimeTableView> {
final periodsSlots = 15;
final double containerHeight = 55.0;
final double containerWidth = 80;
final days = [
"Monday",
"Tuesday",
"Wednesday",
"Thursday",
"Friday",
"Saturday",
];
final subjects = [
"Maths",
"Hindi",
"English",
"Chemistry",
"History",
"Geography",
];
late ScrollController mainController;
late ScrollController secondController;
#override
void initState() {
super.initState();
secondController = ScrollController();
mainController = ScrollController()
..addListener(() {
if (mainController.hasClients && secondController.hasClients) {
secondController.jumpTo(mainController.offset);
}
});
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text("Time Table"),
),
body: Padding(
padding: const EdgeInsets.all(8.0),
child: PageView(
children: [
Column(
mainAxisSize: MainAxisSize.min,
children: [
Row(
mainAxisSize: MainAxisSize.min,
children: [
// Top header View
SizedBox(
height: containerHeight,
width: containerWidth,
child: CustomPaint(
painter: RectanglePainter(),
child: Stack(
children: const [
Align(
alignment: Alignment.topRight,
child: Padding(
padding: EdgeInsets.all(4.0),
child: Text("Day"),
),
),
Align(
alignment: Alignment.bottomLeft,
child: Padding(
padding: EdgeInsets.all(4.0),
child: Text("Period"),
),
),
],
),
),
),
Expanded(
child: SizedBox(
height: containerHeight,
child: SingleChildScrollView(
physics: const ClampingScrollPhysics(),
padding: EdgeInsets.zero,
scrollDirection: Axis.horizontal,
controller: mainController,
child: Row(
children: List<Widget>.generate(
days.length,
(index) => Container(
height: containerHeight,
width: containerWidth,
color: bgColorHeader(index),
child: Padding(
padding:
const EdgeInsets.symmetric(horizontal: 8),
child: Center(child: Text(days[index])),
),
),
),
),
),
),
)
],
),
SizedBox(
// Added fixed size to scroll listView horizontal
height: 500,
child: ListView.builder(
physics: const ClampingScrollPhysics(),
padding:
EdgeInsets.zero, // remove listview default padding.
shrinkWrap: true,
scrollDirection: Axis.vertical,
itemCount: periodsSlots,
itemBuilder: (context, index) => Container(
height: containerHeight,
width: containerWidth,
color: bgColorHeader(index),
child: Row(
mainAxisSize: MainAxisSize.min,
children: [
// period header
Padding(
padding: EdgeInsets.zero,
child: SizedBox(
width: containerWidth,
height: containerHeight,
child: Center(child: Text("period ${index + 1}")),
),
),
// period subjects
Expanded(
child: SizedBox(
height: containerHeight,
child: SingleChildScrollView(
physics: const ClampingScrollPhysics(),
padding: EdgeInsets.zero,
scrollDirection: Axis.horizontal,
controller: secondController,
child: Row(
children: List<Widget>.generate(
subjects.length,
(index) => Container(
color: Colors.white,
child: Container(
height: containerHeight,
width: containerWidth,
color: bgColorSubject(index),
child: Center(
child: Padding(
padding: const EdgeInsets.symmetric(
horizontal: 4),
child: Text(subjects[index]),
)),
),
),
),
),
),
),
)
],
),
),
),
)
],
),
],
),
),
);
}
// Alternate background colors
Color bgColorHeader(int index) =>
index % 2 == 0 ? Colors.cyan.withOpacity(0.5) : Colors.cyanAccent;
Color bgColorSubject(int index) =>
index % 2 == 0 ? Colors.grey.withOpacity(0.5) : Colors.grey;
}
// Draw cross line from top left container
class RectanglePainter extends CustomPainter {
#override
void paint(Canvas canvas, Size size) {
final backgroundPaint = Paint()
..color = Colors.cyanAccent
..strokeWidth = 2.0
..strokeCap = StrokeCap.round;
final crossLine = Paint()
..color = Colors.white
..strokeWidth = 2.0
..strokeCap = StrokeCap.round;
// Draw the rectangle
canvas.drawRect(Offset.zero & size, backgroundPaint);
// Draw the cross line
canvas.drawLine(Offset.zero, Offset(size.width, size.height), crossLine);
//canvas.drawLine(Offset(0, size.height), Offset(size.width, 0), crossLine);
}
#override
bool shouldRepaint(RectanglePainter oldDelegate) => false;
}
Scrolling widgets will create a default scroll controller (ScrollController class) if none is provided. A scroll controller creates a ScrollPosition to manage the state specific to an individual Scrollable widget.
To link our scroll controllers we’ll use linked_scroll_controller, a scroll controller that allows two or more scroll views to be in sync.
import 'package:flutter/material.dart';
import 'package:linked_scroll_controller/linked_scroll_controller.dart';
class ScrollDemo extends StatefulWidget {
#override
_ScrollDemoState createState() => _ScrollDemoState();
}
class _ScrollDemoState extends State<ScrollDemo> {
final List<String> colEntries = "ABCDEFGHIJKLMNOPQRSTUVWXYZ".split('');
final List<String> rowEntries =
Iterable<int>.generate(15).map((e) => e.toString()).toList();
late LinkedScrollControllerGroup _horizontalControllersGroup;
late ScrollController _horizontalController1;
late ScrollController _horizontalController2;
late LinkedScrollControllerGroup _verticalControllersGroup;
late ScrollController _verticalController1;
late ScrollController _verticalController2;
#override
void initState() {
super.initState();
_horizontalControllersGroup = LinkedScrollControllerGroup();
_horizontalController1 = _horizontalControllersGroup.addAndGet();
_horizontalController2 = _horizontalControllersGroup.addAndGet();
_verticalControllersGroup = LinkedScrollControllerGroup();
_verticalController1 = _verticalControllersGroup.addAndGet();
_verticalController2 = _verticalControllersGroup.addAndGet();
}
#override
void dispose() {
_horizontalController1.dispose();
_horizontalController2.dispose();
_verticalController1.dispose();
_verticalController2.dispose();
super.dispose();
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('sync scroll demo'),
),
body: SafeArea(
child: Padding(
padding: const EdgeInsets.all(20),
child: Column(
children: <Widget>[
Row(
children: <Widget>[
Container(
width: 75,
height: 75,
color: Colors.grey[200],
),
const SizedBox(width: 10),
Container(
height: 75,
width: 400,
color: Colors.blue[100],
child: SingleChildScrollView(
scrollDirection: Axis.horizontal,
controller: _horizontalController2,
child: HeaderContainer(rowEntries: rowEntries),
),
)
],
),
const SizedBox(height: 10),
Row(
children: <Widget>[
Container(
width: 75,
height: 400,
color: Colors.blue[100],
child: SingleChildScrollView(
controller: _verticalController2,
child: ColumnContainer(
colEntries: colEntries,
),
),
),
const SizedBox(width: 10),
SizedBox(
width: 400,
height: 400,
child: SingleChildScrollView(
controller: _verticalController1,
child: SingleChildScrollView(
scrollDirection: Axis.horizontal,
controller: _horizontalController1,
child: BodyContainer(
rowEntries: rowEntries,
colEntries: colEntries,
),
),
),
)
],
),
],
),
),
),
);
}
}
class ColumnContainer extends StatelessWidget {
final List<String> colEntries;
const ColumnContainer({
Key? key,
required this.colEntries,
}) : super(key: key);
#override
Widget build(BuildContext context) {
int numberOfRows = colEntries.length;
return Column(
children: List.generate(
numberOfRows,
(i) {
return Container(
height: 75,
width: 75,
decoration: BoxDecoration(border: Border.all(color: Colors.white)),
child: Center(child: Text(colEntries[i])),
);
},
),
);
}
}
class HeaderContainer extends StatelessWidget {
final List<String> rowEntries;
const HeaderContainer({
Key? key,
required this.rowEntries,
}) : super(key: key);
#override
Widget build(BuildContext context) {
int _numberOfColumns = rowEntries.length;
return Row(
children: List.generate(
_numberOfColumns,
(i) {
return Container(
height: 75,
width: 75,
decoration: BoxDecoration(border: Border.all(color: Colors.white)),
child: Center(child: Text(rowEntries[i])),
);
},
),
);
}
}
class BodyContainer extends StatelessWidget {
final List<String> colEntries;
final List<String> rowEntries;
const BodyContainer({
Key? key,
required this.colEntries,
required this.rowEntries,
}) : super(key: key);
#override
Widget build(BuildContext context) {
int _numberOfColumns = rowEntries.length;
int _numberOfLines = colEntries.length;
return Column(
children: List.generate(_numberOfLines, (y) {
return Row(
children: List.generate(_numberOfColumns, (x) {
return TableCell(item: "${colEntries[y]}${rowEntries[x]}");
}),
);
}),
);
}
}
class TableCell extends StatelessWidget {
final String item;
const TableCell({
Key? key,
required this.item,
}) : super(key: key);
#override
Widget build(BuildContext context) {
return Container(
height: 75,
width: 75,
decoration: BoxDecoration(border: Border.all(color: Colors.grey)),
child: Center(child: Text(item)),
);
}
}
I found these solutions from these 2 links.
Flutter: How to create linked scroll widgets
Flutter: Creating a two-direction scrolling table with a fixed head and column
I'm having problems with flex widget with a column inside where the children have a fixed height (constrained to min and max).
I have to build a screen with a column with many rows as children and each row has some column children and this column has widgets with restricted height.
I want each row to fit the maximum height of the inner column and at the same time all rows to fit the full height of the screen.
I mean, I want the children height has priority over his parent.
EDIT: I attached an image and the code to see the problem.
class SecheduleDatatable extends StatelessWidget {
final DateTime initDate;
final int dayTreshold;
final List<ActivityItem> items;
final bool buildHeaders;
SecheduleDatatable({
required this.items,
required this.initDate,
required this.dayTreshold,
this.buildHeaders = false,
});
final double spaceBetween = 64;
final double leftPadding = 32;
double minItemHeight = 100;
double maxItemHeight = 150;
double fontSize = 45;
double headerHeight = 120;
void _initSizes(BuildContext context) {
final screenWidth = MediaQuery.of(context).size.width;
if (screenWidth > 4000) {
fontSize = 100;
minItemHeight = 0;
maxItemHeight = 180;
headerHeight = 180;
} else if (screenWidth > 1920) {
fontSize = 45;
minItemHeight = 60;
maxItemHeight = 120;
headerHeight = 120;
} else {
fontSize = 25;
minItemHeight = 0;
maxItemHeight = 80;
headerHeight = 80;
}
}
#override
Widget build(BuildContext context) {
_initSizes(context);
return Column(
mainAxisSize: MainAxisSize.max,
children: [
Flexible(child: _createColumns()),
..._createRows(),
],
);
}
bool hasToExpand(String time) {
final days = _createDays(true);
days.addAll(_createDays(false));
final groupedByTimeSort = items.groupBy((p0) => p0.dateFormated);
for (DateTime date in days) {
final tempItems = groupedByTimeSort[time]
?.where((element) => element.date.getInitDay() == date.getInitDay())
.toList();
if (tempItems != null && tempItems.length > 1) return false;
}
return true;
}
Widget _createColumns() {
final days = _createDays(true);
days.addAll(_createDays(false));
return IntrinsicHeight(
child: Row(
children: [
Expanded(
child: Row(
children: [
Expanded(child: _clock()),
Expanded(flex: 3, child: _header(days[0].formatHeaderDate())),
Expanded(flex: 3, child: _header(days[1].formatHeaderDate())),
],
)),
/* Spacer(
flex: 1,
), */
Expanded(
child: Row(
children: [
Expanded(child: Container()),
Expanded(flex: 4, child: _header(days[2].formatHeaderDate())),
Expanded(flex: 4, child: _header(days[3].formatHeaderDate())),
Expanded(child: Container())
],
)),
],
),
);
}
List<Widget> _createRows() {
final days = _createDays(true);
days.addAll(_createDays(false));
final groupedByTimeSort = items.groupBy((p0) => p0.dateFormated);
Widget _getItemByDate(String time, DateTime date) {
final maybeItems = groupedByTimeSort[time]
?.where((element) => element.date.getInitDay() == date.getInitDay());
if (maybeItems != null) {
return Column(
mainAxisSize: MainAxisSize.min,
children: maybeItems
.map((e) => hasToExpand(time)
? Flexible(child: _item(e, kSpacing / 2))
: Flexible(child: _item(e, 0)))
.toList());
} else {
return Container();
}
}
Widget _getItem(String time, int pos, int flex) {
return Expanded(flex: flex, child: IntrinsicHeight(child: _getItemByDate(time, days[pos])));
}
final rows = groupedByTimeSort.keys.map((time) {
final row = Flexible(
child: IntrinsicHeight(
child: Row(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
Expanded(
child: IntrinsicHeight(
child: Row(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
Expanded(child: _hour(time)),
_getItem(time, 0, 3),
_getItem(time, 1, 3),
],
),
)),
Expanded(
child: IntrinsicHeight(
child: Row(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
Expanded(child: Container()),
_getItem(time, 2, 4),
_getItem(time, 3, 4),
Expanded(child: Container()),
],
),
))
],
)));
/* final row = IntrinsicHeight(
child: Row(children: [
Expanded(child: _hour(time)),
...days.map((date) => Expanded(flex: 3, child: _getItemByDate(time, date))).toList()
])); */
return row;
}).toList();
return rows;
}
Widget _item(ActivityItem item, double spacing) {
return Container(
width: double.infinity,
margin: EdgeInsets.symmetric(vertical: 2, horizontal: 2),
padding: EdgeInsets.all(spacing),
decoration: BoxDecoration(
color: item.activityModel!.color, borderRadius: BorderRadius.circular(15)),
child: Center(
child: Text(
item.activityModel!.getTitle(),
maxLines: 1,
textAlign: TextAlign.center,
style: TextStyle(color: Colors.white, fontWeight: FontWeight.bold, fontSize: fontSize),
),
));
}
Widget _emptyItem() {
return Container(
// constraints: BoxConstraints(minHeight: minItemHeight, maxHeight: maxItemHeight),
width: double.infinity,
margin: EdgeInsets.symmetric(vertical: 1),
padding: EdgeInsets.all(kSpacing / 2),
child: FittedBox(
fit: BoxFit.scaleDown,
child: Text(
"",
style: TextStyle(color: Colors.white, fontWeight: FontWeight.bold, fontSize: fontSize),
),
));
}
Widget _clock() {
return Container(
padding: EdgeInsets.symmetric(horizontal: kSpacing, vertical: 4),
decoration: BoxDecoration(borderRadius: BorderRadius.circular(15)),
child: FittedBox(
fit: BoxFit.contain,
child: Padding(
padding: const EdgeInsets.all(8.0),
child: Icon(
FeatherIcons.clock,
),
),
),
);
}
Widget _hour(String time) {
return Container(
margin: EdgeInsets.all(2),
padding: EdgeInsets.symmetric(horizontal: kSpacing, vertical: 4),
decoration: BoxDecoration(color: Colors.black54, borderRadius: BorderRadius.circular(15)),
child: Align(
alignment: Alignment.topCenter,
child: FittedBox(
fit: BoxFit.contain,
child: Text(
time,
style: TextStyle(color: Colors.white, fontSize: fontSize, fontWeight: FontWeight.bold),
),
),
),
);
}
Widget _header(String text) {
return Container(
height: headerHeight,
margin: EdgeInsets.symmetric(vertical: 2, horizontal: 2),
padding: EdgeInsets.all(kSpacing / 2),
decoration: BoxDecoration(color: Colors.black54, borderRadius: BorderRadius.circular(15)),
child: Align(
alignment: Alignment.center,
child: FittedBox(
child: Text(
text,
textAlign: TextAlign.center,
style:
TextStyle(color: Colors.white, fontWeight: FontWeight.bold, fontSize: fontSize),
),
),
));
}
List<DateTime> _createDays(bool first) {
final days = first ? [initDate] : [initDate.add(Duration(days: dayTreshold ~/ 2))];
for (var i = first ? 1 : dayTreshold ~/ 2;
i < (first ? dayTreshold ~/ 2 : dayTreshold - 1);
i++) {
days.add(days.last.add(Duration(days: 1)));
}
return days;
}
}
I want that the parent row take height of column child. Notice the rows are flexible to fit responsiveness to screen changes.
So really, in summarize, I want the rows are responsiveness but its inner columns get max height.
Sorry is not easy to explain it.
I added singlechildscrollview and I set the height of the container for the column items at 320 for four items of 80.
import 'package:flutter/material.dart';
import 'package:flutter/gestures.dart';
class MyCustomScrollBehavior extends MaterialScrollBehavior {
// Override behavior methods and getters like dragDevices
#override
Set<PointerDeviceKind> get dragDevices => {
PointerDeviceKind.touch,
PointerDeviceKind.mouse,
};
}
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
// This widget is the root of your application.
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
scrollBehavior: MyCustomScrollBehavior(),
debugShowCheckedModeBanner:false,
home: Test_Flexible(),
);
}
}
class Test_Flexible extends StatefulWidget {
Test_Flexible({Key? key}) : super(key: key);
#override
State<Test_Flexible> createState() => _Test_FlexibleState();
}
class _Test_FlexibleState extends State<Test_Flexible> {
#override
Widget build(BuildContext context) {
return Scaffold(appBar: AppBar(title: Text("Test Flexible"),) ,body:
SingleChildScrollView(child:
Column(
mainAxisAlignment: MainAxisAlignment.start,
children: [
Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Expanded(
flex: 1,
child: Container(
height: 100,
color: Colors.orange,
)),
Expanded(
flex: 3,
child: Container(
height: 320,
color: Colors.blue,
child:(Column(children:[
Flexible(
child: Container(
height: 80,
color: Colors.purple,
),
),
Flexible(
child: Container(
height: 80,
color: Colors.green,
),
),
Flexible(
child: Container(
height: 80,
color: Colors.yellow,
),
),
Flexible(
child: Container(
height: 80,
color: Colors.pink,
),
),
]))
)),
Expanded(
flex: 3,
child: Container(
height: 100,
color: Colors.blueGrey,
)),
],)
])
,));
}
}
I want to build a portfolio website with flutter and I can't find fade-in animation while scrolling down,
there are animatedBox and a lot of animation but none of them have listeners for fading in while scrolling down.
Can anyone help me with this? An example would be more helpful.
Thank you
After a while, I find a way to do that, we should use the scrollController and mediaQuery for riching this goal,
source code
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: 'Ali Azimoshan',
debugShowCheckedModeBanner: false,
home: MyHomePage(),
);
}
}
class MyHomePage extends StatefulWidget {
#override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
ScrollController _scrollController;
var selectedSlide;
imageBox() {
return Container(
width: MediaQuery.of(context).size.width,
height: MediaQuery.of(context).size.height,
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Container(
width: MediaQuery.of(context).size.width / 3,
height: MediaQuery.of(context).size.height / 3,
decoration: BoxDecoration(
image: DecorationImage(
image: AssetImage(
'assets/images/image-1.jpg',
),
),
),
),
Container(
width: MediaQuery.of(context).size.width / 3,
height: MediaQuery.of(context).size.height / 3,
decoration: BoxDecoration(
image: DecorationImage(
image: AssetImage(
'assets/images/image-2.jpg',
),
),
),
),
Container(
width: MediaQuery.of(context).size.width / 3,
height: MediaQuery.of(context).size.height / 3,
decoration: BoxDecoration(
image: DecorationImage(
image: AssetImage(
'assets/images/image-3.jpg',
),
),
),
),
],
),
);
}
List allSlides = [
{'widget': Widget, 'selected': false},
{'widget': Widget, 'selected': false},
{'widget': Widget, 'selected': false},
{'widget': Widget, 'selected': false},
{'widget': Widget, 'selected': false},
{'widget': Widget, 'selected': false},
{'widget': Widget, 'selected': false},
{'widget': Widget, 'selected': false},
{'widget': Widget, 'selected': false}
];
#override
void initState() {
super.initState();
_scrollController = ScrollController();
_scrollController.addListener(changeSelector);
setState(() {
selectedSlide = allSlides[0];
selectedSlide['selected'] = true;
});
}
changeSelector() {
var maxScrollVal = _scrollController.position.maxScrollExtent;
var divisor = (maxScrollVal / allSlides.length) + 20;
var scrollValue = _scrollController.offset.round();
var slideValue = (scrollValue / divisor).round();
// var currentSlide = allSlides.indexWhere((slide) => slide['selected']);
setState(() {
// allSlides[currentSlide]['selected'] = false;
selectedSlide = allSlides[slideValue];
selectedSlide['selected'] = true;
});
}
#override
Widget build(BuildContext context) {
return Scaffold(
body: Row(
children: <Widget>[
Container(
width: MediaQuery.of(context).size.width,
child: ListView(
controller: _scrollController,
children: allSlides.map((element) {
return getCards(element);
}).toList(),
),
)
],
),
);
}
Widget getCards(slide) {
return Padding(
padding: EdgeInsets.all(0),
child: AnimatedCrossFade(
firstChild: imageBox(),
duration: Duration(seconds: 1),
secondChild: Container(
width: MediaQuery.of(context).size.width,
height: MediaQuery.of(context).size.height,
color: Colors.transparent,
),
crossFadeState: slide['selected']
? CrossFadeState.showFirst
: CrossFadeState.showSecond,
),
);
}
}
Ok here's a little demo
here's the code
import 'package:flutter/material.dart';
import 'package:transparent_image/transparent_image.dart';
class overall extends StatefulWidget {
#override
_HomePageState createState() => _HomePageState();
}
class _HomePageState extends State<overall> {
double offset = 0;
#override
Widget build(BuildContext context) {
final height = MediaQuery.of(context).size.height;
final width = MediaQuery.of(context).size.width;
final nameStyle = Theme.of(context).textTheme.headline2;
final descriptionStyle = Theme.of(context).textTheme.headline4;
final workStyle = Theme.of(context).textTheme.headline6;
return Material(
child: NotificationListener<ScrollNotification>(
onNotification: updateOffsetAccordingToScroll,
child: ScrollConfiguration(
behavior: NoScrollGlow(),
child: Stack(
children: <Widget>[
Positioned(
top: -.45 * offset,
child: FadeInImage.memoryNetwork(
placeholder: kTransparentImage,
image: backgroundImage,
height: height,
width: width,
fit: BoxFit.fitWidth,
),
),
Positioned(
top: -.25 * offset,
child: SizedBox(
height: height,
width: width,
child: Align(
alignment: Alignment(0, 0),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
circleIcon(profileicon, 100),
Text(
'My Name',
style: nameStyle.copyWith(
color: Colors.white,
),
),
SizedBox(height: 20),
Text(
'Representing my core values here',
style: descriptionStyle.copyWith(
color: Colors.white,
),
),
Padding(
padding: const EdgeInsets.only(top: 18.0),
child: Text(
"Currently Working with",
style: workStyle.copyWith(
color: Colors.white,
),
),
),
Padding(
padding: const EdgeInsets.only(top: 18.0),
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Padding(
padding: const EdgeInsets.only(right: 10.0),
child: circleIcon(fluttericon, 40),
),
Padding(
padding: const EdgeInsets.only(left: 20.0),
child: circleIcon(darticon, 40)),
],
),
)
],
)),
),
),
SingleChildScrollView(
child: Column(
children: <Widget>[
SizedBox(height: height),
Container(
height: height,
width: width,
color: Colors.blueAccent,
)
],
),
)
],
),
),
),
);
}
bool updateOffsetAccordingToScroll(ScrollNotification scrollNotification) {
setState(() => offset = scrollNotification.metrics.pixels);
return true;
}
}
class NoScrollGlow extends ScrollBehavior {
#override
Widget buildViewportChrome(
BuildContext context,
Widget child,
AxisDirection axisDirection,
) {
return child;
}
}
circleIcon(String icon, size) {
return CircleAvatar(
radius: size,
backgroundImage: NetworkImage(icon),
);
}
const backgroundImage = 'https://wallpaperaccess.com/full/7033.jpg';
const profileicon =
'https://flutter.github.io/assets-for-api-docs/assets/widgets/owl.jpg';
const darticon =
'data:image/png;base64,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';
const fluttericon =
'https://cdn.iconscout.com/icon/free/png-512/flutter-2038877-1720090.png';
I have created a custom dropdown widget, to select one option form a list that i load it from local json file.
When this dropdown field is at the bottom of the screen, the options can not be displayed, because of using overlay element.
Can you help me, how can I solve htis issue?
here is the image that shows my problem
Here is my custom dropdown
import 'package:flutter/material.dart';
class CustomDropdown extends StatefulWidget {
final TextEditingController controller;
final List<Map> items;
final String label;
final String value;
const CustomDropdown({Key key, #required this.controller, #required this.items, this.label, this.value}) : super(key: key);
#override
_CustomDropdownState createState() => _CustomDropdownState();
}
class _CustomDropdownState extends State<CustomDropdown> {
final FocusNode _focusNode = FocusNode();
OverlayEntry _overlayEntry;
final LayerLink _layerLink = LayerLink();
bool isOpened = false;
#override
void initState() {
super.initState();
widget.controller.text = widget.value;
_focusNode.addListener(() {
if (_focusNode.hasFocus) {
this._overlayEntry = this._createOverlayEntry();
Overlay.of(context).insert(this._overlayEntry);
} else {
this._overlayEntry.remove();
}
});
}
OverlayEntry _createOverlayEntry() {
RenderBox renderBox = context.findRenderObject();
var size = renderBox.size;
var offset = renderBox.localToGlobal(Offset.zero);
return OverlayEntry(
// opaque: true,
builder: (context) => Positioned(
// left: offset.dx,
// top: offset.dy + size.height + 5.0,
width: size.width,
child: CompositedTransformFollower(
link: this._layerLink,
showWhenUnlinked: false,
offset: Offset(0.0, size.height + 5.0),
child: Material(
elevation: 12.0,
child: ListView.builder(
padding: EdgeInsets.zero,
scrollDirection: Axis.vertical,
shrinkWrap: true, // new line
// physics: NeverScrollableScrollPhysics(), // new line
itemCount: widget.items.length,
itemBuilder: (_, index) {
return ListTile(
title: Column(
children: [
SizedBox(
height: 20,
),
Text(widget.items[index]["text"]),
SizedBox(
height: 20,
),
Divider()
],
),
onTap: () {
print("${widget.items[index]["text"]} Tapped");
setState(() {
_focusNode.unfocus();
widget.controller.text = widget.items[index]["text"];
});
},
);
},
),
),
),
),
);
}
#override
Widget build(BuildContext context) {
return CompositedTransformTarget(
link: this._layerLink,
child: TextFormField(
controller: widget.controller,
readOnly: true,
// initialValue: 'Test',
focusNode: this._focusNode,
decoration: InputDecoration(
labelText: widget.label.toUpperCase(),
isDense: true,
),
),
);
}
}
and here where i use it:
Form(
key: _formKey,
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
'Wollen Sie Ihr Profile mit einem Passwort schützen?'.toUpperCase(),
style: TextStyle(fontSize: 20.0, color: theme.inputTextColor),
),
Padding(
padding: const EdgeInsets.only(top: 15.0),
child: _buildFaceIdOptions(),
),
Padding(
padding: const EdgeInsets.only(top: 15.0),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Text(
'FaceID verwenden',
style: TextStyle(fontSize: 18.0),
),
_buildToggleButton()
],
),
),
SizedBox(
height: 20,
),
Padding(
padding: const EdgeInsets.only(top: 15.0),
child: _buildPassword(),
),
SizedBox(
height: 20,
),
Padding(
padding: const EdgeInsets.only(top: 15.0),
child: _buildRepeatPassword(),
),
SizedBox(
height: 20,
),
Padding(padding: const EdgeInsets.only(top: 15.0), child: CustomDropdown(controller: questionController, items: _questionList, label: 'Sicherheitsfrage', value: '',)),
SizedBox(
height: 20,
),
// Padding(
// padding: const EdgeInsets.only(top: 15.0),
// child: _buildPassword(),
// ),
SizedBox(
height: 120,
)
],
),
)
You can make the list inside the Overlay scrollable.
You have to set all possible values in the Positioned widget inside OverlayEntry otherwise its content won't be scrollable: if you set width then you have to also set top, bottom and left (or right but not both, read the Positioned widget specifications for that).
Once you set those values the Positioned widget contents will be scrollable.
this screenshot of an No Material widget found
I try to add stars RateBar as below code but i got an error no material widget found.
what i need to do is that when i pressed on this flatButton i got a window to rate the order and submit this rate, how can i do that through my code below, or to inform me how to handle it
this is the widget of StarRating
import 'package:flutter/material.dart';
typedef void RatingChangeCallback(double rating);
class StarRating extends StatelessWidget {
final int starCount;
final double rating;
final RatingChangeCallback onRatingchanged;
final Color color;
StarRating({this.starCount=5, this.rating = .0, this.onRatingchanged, this.color});
Widget buildStar(BuildContext context, int index){
Icon icon;
if (index >= rating) {
icon = Icon(
Icons.star_border,
color: Theme.of(context).buttonColor
);
}
else if(index > rating - 1 && index < rating){
icon = Icon(
Icons.star_half,
color: Theme.of(context).primaryColor,
);
}else{
icon = Icon(
Icons.stars,
color: Theme.of(context).primaryColor,
);
}
return InkResponse(
onTap: onRatingchanged==null ? null : ()=> onRatingchanged(index+1.0),
child: icon,
);
}
#override
Widget build(BuildContext context) {
return Row(
children: List.generate(starCount, (index)=>buildStar(context, index)),
);
}
}
and this is the Screen to view the starBar:
import 'package:felsaree/widgets/star.rating.dart';
import 'package:flutter/material.dart';
class StarRatingScreen extends StatefulWidget {
static const routeName = '/starRating';
#override
_StarRatingScreenState createState() => _StarRatingScreenState();
}
class _StarRatingScreenState extends State<StarRatingScreen> {
double rating =3.5;
#override
Widget build(BuildContext context) {
return StarRating(
rating: rating,
onRatingchanged: (rating) => setState(() => this.rating = rating),
);
}
}
and in orderDetails screen through the flatbutton i need to show this Star Rate:
import 'package:felsaree/providers/order_provider.dart';
import 'package:felsaree/screens/star_rating_screen.dart';
import 'package:felsaree/widgets/star.rating.dart';
import 'package:flutter/material.dart';
import 'package:intl/intl.dart';
import 'package:provider/provider.dart';
class OrderDetails extends StatefulWidget {
static const routeName = '/orderDetails';
#override
_OrderDetailsState createState() => _OrderDetailsState();
}
class _OrderDetailsState extends State<OrderDetails> {
double rating = 3.5;
// Widget ratingChange(double rating){
// return StarRating(
// rating: rating,
// onRatingchanged: (rating)=>this.rating = rating,);
// }
#override
Widget build(BuildContext context) {
final mediaQuery = MediaQuery.of(context).size.height;
final orderId = ModalRoute.of(context).settings.arguments as int;
final orderProvider = Provider.of<OrderProvider>(context, listen: false);
final order = orderProvider.findOrderById(orderId);
AppBar appBar = AppBar(title: Text(order.restaurantName),);
double _totalPrice =orderProvider.totalItemsPrice(order.orderItems);
bool _isAddress = orderProvider.checkUserAdress(order.address);
return Scaffold(
appBar: appBar,
body: Column(
children: <Widget>[
Card(
elevation: 4,
margin: EdgeInsets.all(10),
child: Padding(
padding: EdgeInsets.all(10),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
Column(
children: <Widget>[
Text(order.id.toString()),
SizedBox(height: 4,),
Text(order.restaurantName),
SizedBox(height: 4,),
Text(order.branchName),
SizedBox(height: 4,),
],
),
Column(
children: <Widget>[
Text(DateFormat.yMd().format(DateTime.now())),
SizedBox(height: 15,),
Text('InProgress'),
SizedBox(height: 15,)
],
)
],
),),
),
Container(
margin: EdgeInsets.all(10),
padding: EdgeInsets.all(10),
decoration: BoxDecoration(
color: Colors.grey[100],
border: Border.all(width: 2, color: Colors.grey)
) ,
child: Column(
children: <Widget>[
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
Text('Price'),
Text('${_totalPrice}L.E'),
Text('Total: ${order.price}L.E')
],
),
SizedBox(height: 10,),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
Text('PC Discount'),
Text('${order.discountValue}L.E'),
Text(''),
],
),
SizedBox(height: 10,),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
Text('service Tax'),
Text('${order.serviceTax}L.E'),
Text(''),
],
),
SizedBox(height: 10,),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
Text('Delivery'),
Text('${order.delivery}L.E'),
Text(''),
],
),
SizedBox(height: 10,),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
Text('Vat'),
Text('${order.vatAmount}L.E'),
Text(''),
],
),
],
),
),
Container(
decoration: BoxDecoration(
color: Colors.white,
border: Border.all(color: Colors.grey),
borderRadius: BorderRadius.circular(10),
),
padding: EdgeInsets.all(10),
margin: EdgeInsets.only(bottom: 20),
height: (mediaQuery
- appBar.preferredSize.height
- MediaQuery.of(context).padding.top)*0.30,
width: MediaQuery.of(context).size.width*.8,
child: ListView.builder(
itemCount: order.orderItems.length,
itemBuilder: (ctx, index){
final item = order.orderItems[index];
if(item.userComments == ''){
String userComment= 'no comment';
item.userComments = userComment;
}
return ListTile(
leading: CircleAvatar(
backgroundImage: NetworkImage(item.image,),
),
title: Text(item.itemName),
subtitle: Text('count: ${item.count}'),
trailing: Text(item.userComments),
);
}
),
),
Container(
width: double.infinity,
margin: EdgeInsets.only(right: 10, left: 10),
padding: EdgeInsets.symmetric(vertical: 5, horizontal: 10),
color: Colors.grey[100],
child: Text('Delivery Address', style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold),),
),
SizedBox(height: 8),
Container(
width: double.infinity,
padding: EdgeInsets.all(10),
margin: EdgeInsets.all(10),
decoration: BoxDecoration(
border: Border.all(color: Colors.grey[100])
),
child: _isAddress? Text(order.address) : Text('no address found'),
),
FlatButton(
onPressed: ()=>Navigator.of(context).pushNamed(StarRatingScreen.routeName),
child: Text('Rate The Order', style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold),))
],
),
);
}
}
This can be fixed by ensuring that your main includes MaterialApp() and Scaffold() as ancestors of your widgets as so:
void main() {
runApp(MaterialApp(
home: Scaffold(
appBar: AppBar(),
body: YourWidget(),
),
));
}
If, for whatever reason you don't want to use MaterialApp... you can use Material():
void main() {
runApp(
home: Scaffold(
appBar: AppBar(),
body: Material( child: YourWidget()),
),
);
}