How to assign a controller for ListWheelScrollView in Flutter? - flutter

I am using a ListWheelScrollView that is using physics: FixedExtentScrollPhysics(),. I have used various other ScrollControllers in my app. I want to supply a parameter to my ListWheelScrollView so that it uses the same ScrollController as the rest of my widgets. However it does not allow me to supply the controller:mainController parameter along with FixedExtentScrollPhysics(). How can I solve this?
Here this is the declaration of mainController, the on that I'm trying to call in ListWheelScrollView :
final mainController = ScrollController();
The code for my list is :
ListWheelScrollView.useDelegate(
itemExtent: 90,
perspective: 0.0025,
magnification: 1.2,
physics: FixedExtentScrollPhysics(),
diameterRatio: 4,
// controller: mainController,
offAxisFraction: 0.42,
useMagnifier: true,
childDelegate: ListWheelChildBuilderDelegate(
builder: (
context,
index,
) {
return Column(
children: [
ListTile(
isThreeLine: false,
trailing: indexTrailing(index, duration, true),
title: Row(
children: <Widget>[
Padding(
padding: EdgeInsets.only(
right: 10, top: 5, bottom: 5),
child: ClipRRect(
borderRadius: BorderRadius.circular(12.0),
child: Container(
height: 60,
width: 60,
child: Image.network(
'https://www.ikea.com/in/en/images/products/smycka-artificial-flower-rose-red__0903311_PE596728_S5.JPG'),
),
),
),
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
'Hello',
style: GoogleFonts.montserrat(
wordSpacing: 0,
letterSpacing: 0,
textStyle: kTasksStyle.copyWith(
fontSize: 15,
color: kDarkBlue,
fontWeight: FontWeight.w500),
),
),
SizedBox(
height: 5,
),
SizedBox(
width: MediaQuery.of(context).size.width *
0.62,
child: RichText(
maxLines: 2,
overflow: TextOverflow.ellipsis,
text: TextSpan(
text: "This is a rose",
style: GoogleFonts.montserrat(
textStyle: kTasksStyle.copyWith(
fontSize: 12,
color: kGrey,
fontWeight: FontWeight.normal),
),
),
),
)
],
),
),
],
),
),
Padding(
padding: const EdgeInsets.only(
left: 18.0, right: 18, top: 5, bottom: 5),
child: Divider(
height: 1,
color: Colors.grey.withOpacity(0.2),
thickness: 1,
),
),
],
);
},
childCount: 9),
),
This is the error that I get when I supply the controller parameter along with FixedExtentScrollPhysics():
'package:flutter/src/widgets/scroll_position.dart': Failed assertion: line 504 pos 12: 'haveDimensions == (_lastMetrics != null)': is not true.
The relevant error-causing widget was
ListWheelScrollView
and
The following assertion was thrown during performLayout():
FixedExtentScrollPhysics can only be used with Scrollables that uses the FixedExtentScrollController
'package:flutter/src/widgets/list_wheel_scroll_view.dart':
Failed assertion: line 485 pos 7: 'position is _FixedExtentScrollPosition'

Just use;
FixedExtentScrollController();
instead of
ScrollController();

Related

Flutter ListView Text show on multiLine if overflow

I have A listView in which I have another listview to show simple text in horizontal but the issue is its overflow on the left side If I give width to listview it's going to scroll list. I want if it's overflow then it will simply go to the next line instead of overflow or scroll.
My code
Expanded(
child: new ListView.builder(
itemCount: respondedData3['data'].length,
shrinkWrap: true,
scrollDirection: Axis.vertical,
physics: ScrollPhysics(),
itemBuilder: (context, index) {
String TimeFormat = DateFormat("yyyy-MM-dd").format(DateTime.parse(respondedData3['data'][index]['appointmentDate']));
return Padding(
padding: const EdgeInsets.only(left: 15, right: 15),
child: Container(
child: GestureDetector(
onTap: () async {
Navigator.pop(context);
},
// onTap: widget.onPressed,
child: Stack(children: [
Container(
height: 80,
width: double.infinity,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
children: [
Column(
children: [
Text(TimeFormat, style: TextStyle(fontSize: 14, fontFamily: 'SegoeUI-Bold', color: kPrimaryColor)),
Text(respondedData3['data'][index]['appointmentTime'].toString(), style: TextStyle(fontSize: 13, fontFamily: 'SegoeUI', color: textGreyColor))
],
),
SizedBox(
width: 10,
),
Container(
color: Colors.grey,
height: 40,
width: 1.5,
),
SizedBox(
width: 10,
),
Column(
children: [
Text(respondedData3['data'][index]['serviceProviderName'].toString(), style: TextStyle(fontSize: 13, fontFamily: 'SegoeUI-Bold', color: textGreyColor)),
Container(
height: 20.0,
child: ListView.builder(
shrinkWrap: true,
scrollDirection: Axis.horizontal,
itemCount: serviceShow.length,
itemBuilder: (BuildContext context, int index) => Text('${serviceShow[index]["Name"]} ${serviceShow[index]["Time"]} ${serviceShow[index]["Price"]}'),
),
),
],
)
],
),
],
),
),
]),
),
),
);
},
),
)
You can see in the image it's showing an overflow error I need to show it in the second line.
ListView.builder(
itemCount: 3,
// respondedData3['data'].length,
shrinkWrap: true,
scrollDirection: Axis.vertical,
physics: ScrollPhysics(),
itemBuilder: (context, index) {
String TimeFormat = "yyyy-MM-dd";
// DateFormat("yyyy-MM-dd").format(
// DateTime.parse(respondedData3['data'][index]['appointmentDate']));
return Padding(
padding: const EdgeInsets.only(left: 15, right: 15),
child: Container(
child: GestureDetector(
onTap: () async {
Navigator.pop(context);
},
// onTap: widget.onPressed,
child: Stack(children: [
Container(
height: 80,
// width: double.infinity,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
mainAxisSize: MainAxisSize.min,
children: [
Column(
children: [
Text(
TimeFormat,
// style: TextStyle(
// fontSize: 14,
// fontFamily: 'SegoeUI-Bold',
// color: kPrimaryColor,
// ),
),
Text("Time"
// respondedData3['data'][index]
// ['appointmentTime']
// .toString(),
// style: TextStyle(
// fontSize: 13,
// fontFamily: 'SegoeUI',
// color: textGreyColor,
// ),
)
],
),
SizedBox(
width: 10,
),
Container(
color: Colors.grey,
height: 40,
width: 1.5,
),
SizedBox(
width: 10,
),
Expanded(
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
Text(
"serviceProviderName",
// respondedData3['data'][index]
// ['serviceProviderName']
// .toString(),
style: TextStyle(
fontSize: 13,
// fontFamily: 'SegoeUI-Bold',
// color: textGreyColor
),
),
Container(
height: 20.0,
child: ListView.builder(
shrinkWrap: true,
scrollDirection: Axis.horizontal,
itemCount: 33,
itemBuilder:
(BuildContext context, int index) =>
Text(
'{serviceShow[index]["Name"]} {serviceShow[index]["Time"]} {serviceShow[index]["Price"]}',
),
),
),
],
),
),
],
),
],
),
),
]),
),
),
);
},
),
add max lines on your Text
Text(
'Your multiline text',
maxLines: 2, //2 or more line you want
overflow: TextOverflow.ellipsis,
),
),
You get this error because you don't tell specific width For displaying Text widget and your getting text is huge.Always remeber, in Text widget => use 'overflow: TextOverflow.ellipsis' . Because in dynamic application, text can be large
Use FittedBox to when you want to try your text in limited width. And you want not get overflow error, use "overflow: TextOverflow.ellipsis"
FittedBox(
child:
Container(
width: 260,
// height: 50,
child: const Text(
"testing1 testing2 testing3 testing4 testing5 testing6 testing7 testing8 testing9 testing10 testing testing testing testing testing testing testing testing testing testing testing testing testing testing testing testing testing testing testing testing testing testing testing testing testing testing testing testing testing testing testing testing testing testing testing testing testing testing testing testing testing testing testing testing testing testing testing testing testing testing testing testing testing testing testing testing testing testing testing testing",
style: TextStyle(
// color: Colors.lightBlueAccent,
fontSize: 17,
fontWeight: FontWeight.w600,
),
maxLines: 4,
overflow: TextOverflow.ellipsis
),
),
)
The text in my app was overflowing too , and maxLines: 2, overflow: TextOverflow.ellipsis, was not working since the text was part of the Expanded(child: ListView.builder( so what I did was
LimitedBox(
maxWidth: 150,
child: Text(
videoInfo[index]["title"],
overflow: TextOverflow.clip,
style: TextStyle(
fontSize: 18,
fontWeight: FontWeight.bold,
),
),
)
use Expanded up your Column example;
Expanded(child:
Column(
children: [
Text ('long text'),
Text ('long text 2')
]
)
);

Flutter align specific widget in column with min width

I'm implementing a chat on my flutter app, and I want my chat-time to be align at the right side of the column (all other widgets should be align left).
My problem is that when I'm using alignment.bottomRight in my column, it extends the column width to max (and I want to keep it min).
The problem:
What I'm trying to achieve:
my column:
return Bubble(
margin: BubbleEdges.only(top: 5, bottom: 5),
elevation: 0.6,
alignment: Alignment.topLeft,
nip: BubbleNip.leftTop,
radius: Radius.circular(10),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
getUserChatTitle(document['userId']),
Padding(
padding: const EdgeInsets.only(top: 3, bottom: 5),
child: SelectableLinkify(
onOpen: onOpenLink,
text: "Text Text Text",
textAlign:
intl.Bidi.detectRtlDirectionality(document['content'])
? TextAlign.right
: TextAlign.left,
textDirection:
intl.Bidi.detectRtlDirectionality(document['content'])
? ui.TextDirection.rtl
: ui.TextDirection.ltr,
style: TextStyle(
fontSize: 16,
height: 1.35,
letterSpacing: -0.1,
fontFamily: 'Arimo',
),
),
),
Align(
alignment: Alignment.bottomRight,
child: Text(
formatTimestampToString(document['timestamp']),
textAlign: TextAlign.left,
style: TextStyle(
color: Colors.grey,
fontSize: 12,
),
),
),
],
),
);
This is indeed not as easy, because you want the bubble to have an "undefined" width - it should adapt to the length of the actual message which is not known before actually placing / drawing the widget on runtime. My suggestion would be to make use of a Stack - I also used it inside a ListView.builder which will probably be the desired use case. Make sure to read my comments in the code block as well:
ListView.builder(
itemCount: 5,
itemBuilder: (context, index) => UnconstrainedBox(
/// Decide whether a message has been received or written by yourself (left or right side)
alignment:
index % 2 == 0 ? Alignment.centerLeft : Alignment.centerRight,
/// ConstrainedBox to make sure chat bubbles don't go from left to right if they are too big - you can change it or even remove it if it's not what you want
child: ConstrainedBox(
constraints: BoxConstraints(
maxWidth: MediaQuery.of(context).size.width / 1.5),
child: Bubble(
margin: BubbleEdges.only(top: 5, bottom: 5),
elevation: 0.6,
/// Alignment and nip has to be adjusted here too
alignment:
index % 2 == 0 ? Alignment.topLeft : Alignment.topRight,
nip: index % 2 == 0 ? BubbleNip.leftTop : BubbleNip.rightTop,
radius: Radius.circular(10),
child: Stack(
children: [
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text('TestUser'),
Padding(
padding: const EdgeInsets.only(top: 3, bottom: 5),
child: Text(
'Text ' * Random().nextInt(50),
style: TextStyle(
fontSize: 16,
height: 1.35,
letterSpacing: -0.1,
),
),
),
/// Adjust the space you want between the actual message and the timestamp here, you could also use a Text widget to use the same height as the actual timestamp - as you like
SizedBox(height: 18.0),
],
),
Positioned(
bottom: 0,
right: 0,
child: Text(
'08.09.2021',
style: TextStyle(
color: Colors.grey,
fontSize: 12,
),
),
),
],
),
),
),
),
),
Replace this:
Align(
alignment: Alignment.bottomRight,
child: Text(
formatTimestampToString(document['timestamp']),
textAlign: TextAlign.right,
style: TextStyle(
color: Colors.grey,
fontSize: 12,
),
),
),
With:
Row(
mainAxisAlignment: MainAxisAlignment.end,
children: [Text(
formatTimestampToString(document['timestamp']),
textAlign: TextAlign.right,
style: TextStyle(
color: Colors.grey,
fontSize: 12,
),
)],
),

onTap event of InkResponse not working for grid item

I am trying to execute a simple click event on the grid item in my list. Below is my code which was build using many answers present on stack overflow but none of them is working for me. I wanted a ripple effect on click hence I have used InkResponse.
#override
Widget build(BuildContext context) {
return Scaffold(
body: GridView.count(
padding: const EdgeInsets.fromLTRB(0, 20, 0, 0),
childAspectRatio: 1.5,
mainAxisSpacing: 30,
crossAxisCount: 3,
children: gridItem(parentCalcList),
)
);
}
List<Widget> gridItem(List<ParentCalculators> mParentCalcList) {
List<Widget> tiles = <Widget>[];
for (int i = 0; i < mParentCalcList.length; i++) {
tiles.add(GridTile(
child: InkResponse(
child: getGridColumn(mParentCalcList.elementAt(i)),
onTap: _gridItemClicked(i),
enableFeedback: true,
)));
}
return tiles;
}
getGridColumn(ParentCalculators calc) {
return Column(
children: [
Padding(
padding: const EdgeInsets.fromLTRB(0, 0, 0, 5),
child: CircleAvatar(
child: Transform.scale(
scale: 1,
child: Image.asset(
calc.icon,
height: 30,
width: 30,
fit: BoxFit.fitWidth,
),
),
backgroundColor: Colors.grey.shade300,
radius: 28,
)),
Flexible(
child: Text(
calc.name,
textAlign: TextAlign.center,
style: GoogleFonts.roboto(
color: Colors.black87,
fontSize: 14,
height: 1.1,
textStyle: Theme.of(context).textTheme.subtitle2,
wordSpacing: 0.5,
letterSpacing: 0.8),
),
),
],
);
}
Thank you for your help and patience.

How to add space between words on separate lines in Flutter?

I want to add space between "Radio Frequency" and "Propagation" vertically i.e something like margin. and also make sure that text does not cut from top or bottom if I increase the font size.
Below is my code, I tried with spacing of letters, words and also decoration param but it did not get desired results. Thank you for your patience :)
#override
Widget build(BuildContext context) {
return Scaffold(
body: GridView.count(
padding: const EdgeInsets.fromLTRB(0, 20, 0, 0),
childAspectRatio: 1.5,
mainAxisSpacing: 30,
crossAxisCount: 3,
children: List.generate(
12,
(index) {
return Center(
child: Column(
children: [
Padding(
padding: const EdgeInsets.fromLTRB(0, 0, 0, 5),
child: CircleAvatar(
child: Transform.scale(
scale: 1,
child: Image.asset(
'assets/icons/radar_icon.png',
height: 30,
width: 30,
fit: BoxFit.fitWidth,
),
),
backgroundColor: Colors.grey.shade300,
radius: 30,
)),
Flexible(
child: Text(
"Radio Frequency Propagation",
textAlign: TextAlign.center,
style: GoogleFonts.roboto(color: Colors.black87, fontSize: 14,height: 0.8),
),
),
],
));
},
),
));
}
You are using height is correct. But I think the problem is the placement of the style parameters.
It should be like this:
Flexible(
child: Text(
"Radio Frequency \nPropagation",
textAlign: TextAlign.center,
style: GoogleFonts.roboto(
textStyle: TextStyle(
color: Colors.black87,
fontSize: 14,
height: 1.5,
),
),
),
);
}

Bottom overflowed inside column while listing with Grid.count

I have problem with column, inside Column i have 3 containers. 1st one has picture inside other two has text. For the first container i want to apply height like 100 for example. but max what can i apply is 60 then it giving bottom overflowed. I am using Grid.count to make grid view and listing them with List.genarate.
PS: Wrapping with expanded effecting first container height, and the container does not have fixed height
Here is my code :
Column(
mainAxisSize: MainAxisSize.max,
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
Container(
height: 90,
decoration: BoxDecoration(
color: Theme.of(context).primaryColor,
borderRadius: BorderRadius.all(Radius.circular(10)),
boxShadow: [
BoxShadow(
color: Theme.of(context).focusColor.withOpacity(0.9),
blurRadius: 4,
offset: Offset(0, 2)),
],
),
width: 90,
child: Hero(
tag: widget.heroTag + widget.product.id,
child: Padding(
padding: const EdgeInsets.all(6.0),
child: CachedNetworkImage(
height: 90,
fit: BoxFit.fill,
imageUrl: this.widget.product.imageUrl,
placeholder: (context, url) => Image.asset(
'assets/img/loading.gif',
fit: BoxFit.cover,
height: 150,
),
errorWidget: (context, url, error) => Icon(Icons.error),
),
),
),
),
Center(
child: Container(
width: 90,
child: Text(
widget.product.name,
textAlign: TextAlign.center,
style: TextStyle(fontSize: 11, fontWeight: FontWeight.bold),
overflow: TextOverflow.ellipsis,
maxLines: 2,
),
),
),
Center(
child: Container(
child: Text(
" ${widget.product.salePrice.toString()} Ft ",
style: TextStyle(
color: Colors.blue[800],
fontSize: 13,
fontWeight: FontWeight.bold),
overflow: TextOverflow.ellipsis,
),
),
)
],
),
Here i am listing them with grid.count and list.genearte :
GridView.count(
scrollDirection: Axis.vertical,
shrinkWrap: true,
primary: false,
mainAxisSpacing: 15.0,
// crossAxisSpacing: 4.0,
padding: EdgeInsets.symmetric(
vertical: 15),
crossAxisCount:
MediaQuery.of(context)
.orientation ==
Orientation.portrait
? 3
: 3,
children: List.generate(
_con.subCategories
.elementAt(0)
.products
.length, (index) {
return ProductGridItemWidget(
heroTag: 'product-grid' +
0.toString() +
index.toString(),
product: _con.subCategories
.elementAt(0)
.products
.elementAt(index),
onPressed: () {
{
_con.addToCart(_con
.subCategories
.elementAt(0)
.products
.elementAt(index));
}
});
}),
)),
Finally found solution from this post
Give a height to the child of GridView
Just need to write this line of code inside GridView.count
childAspectRatio: MediaQuery.of(context).size.width /
(MediaQuery.of(context).size.height / 4),