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.
Related
In my home screen my app shows carousel first then a vertical list of challenges cards retrieved from Cloud Firestore using GridView.builder as follows:
GridView.builder(
scrollDirection: Axis.vertical,
itemCount: _challenges.length,
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 1,
childAspectRatio: MediaQuery.of(context).size.width /
(MediaQuery.of(context).size.height / 4),
),
itemBuilder: (context, index) {
return InkWell(
onTap: () {
if (_challenges[index]["isLocked"] == "true") {
showLockedDialog();
} else {
checkParticipation(index);
if (checkPart == true) {
Navigator.push(
context,
MaterialPageRoute(
builder: (_) =>
ChallengeDetails(_challenges[index])));
}
checkPart = true;
}
},
child: Stack(
children: [
Center(
child: ClipRRect(
borderRadius: BorderRadius.circular(15),
child: Image(
image: NetworkImage(_challenges[index]["image-path"]),
fit: BoxFit.cover,
height: 150,
width: 350,
opacity: _challenges[index]["isLocked"] == "true"
? AlwaysStoppedAnimation(.4)
: null,
),
),
),
Center(
child: Text(
"${_challenges[index]["name"]}\n",
style: TextStyle(
color: Colors.white,
fontSize: 20,
fontWeight: FontWeight.bold),
),
),
Center(
child: Text(
"\n${_challenges[index]["date"]}",
style: TextStyle(
color: Colors.white,
fontSize: 20,
fontWeight: FontWeight.bold),
textDirection: TextDirection.ltr,
)),
Center(
child: SizedBox(
height: 130,
width: 130,
child: _challenges[index]["isLocked"] == "true"
? Image.asset("assets/lock-icon.jpg")
: null,
),
)
],
),
);
});
Everything retrieving fine and it is rendered in my home_screen as follows:
body: Column(
children: [
AdsBanner(),
SizedBox(
height: 30,
),
Padding(
padding: const EdgeInsets.only(right: 8, left: 8, bottom: 5),
child: Row(
children: [
Text(
AppLocalizations.of(context)!.challenges + " ",
style: TextStyle(fontSize: 20),
),
Text(
AppLocalizations.of(context)!.clickToParticipate,
style: TextStyle(fontSize: 15),
)
],
),
),
Expanded(child: ChallengeCard()),
],
),
The problem is that only the GridView area is scrolling and what am seeking for is to scroll the whole screen with the GridView area, I was trying to use the CustomScrollView() but its not working properly.
I'll be thankful for any help.
First in your GridView.builder add these:
GridView.builder(
physics: NeverScrollableScrollPhysics(),
shrinkWrap: true,
...
)
then in your home_screen wrap your column with SingleChildScrollView:
SingleChildScrollView(
child: Column(
children: [
AdsBanner(),
SizedBox(
height: 30,
),
Padding(
...
),
),
You can provide physics: NeverScrollableScrollPhysics() on GridView to disable scroll effect. If you want scrollable as secondary widget use primary: false, to have Full Page scrollable, you can use body:SingleChildScrollView(..) or better using body:CustomScrollView(..)
I want to stack the items inside a Listview.builder but when I try to do so with the Align() class and set its heightfactor: , it gives padding to the top and bottom and I don't want that, does anyone have any idea how do I stack them properly?
My center SyncfusionLinearGauge:
//Center SyncfusionLinearGauge
Expanded(
child: ScrollablePositionedList.builder(
itemScrollController: itemController,
itemCount: _provider.loadedContestants.length,
scrollDirection: Axis.vertical,
shrinkWrap: true,
itemBuilder: (context, index) {
final data = _provider.loadedContestants[index];
return Align(
heightFactor: 0.0001,
child: SfLinearGauge(
// showLabels: false,
// showTicks: false,
// showAxisTrack: false,
axisLabelStyle: TextStyle(color: Colors.white),
majorTickStyle: LinearTickStyle(
color: Colors.white, length: 10),
minorTickStyle:
LinearTickStyle(color: Colors.white),
axisTrackStyle:
LinearAxisTrackStyle(color: Colors.red),
orientation: LinearGaugeOrientation.vertical,
minimum: 0,
maximum: 100,
animationDuration: 500,
markerPointers: [
//User pointer
LinearWidgetPointer(
value: data.points,
position: LinearElementPosition.cross,
offset: 50.0,
animationDuration: 2000,
child: UserCardWidget(
data: data,
),
),
],
),
);
},
),
),
My user card:
class UserCardWidget extends StatelessWidget {
UserCardWidget({Key key, this.data}) : super(key: key);
DemoUserModel data;
#override
Widget build(BuildContext context) {
bool _isKevinTeam = data.team == 'Kevin';
return SingleChildScrollView(
child: Padding(
padding: const EdgeInsets.only(left: 167.0),
child: Row(
mainAxisAlignment: MainAxisAlignment.start,
// mainAxisSize: MainAxisSize.min,
children: [
Container(
width: 15,
height: 15,
decoration: BoxDecoration(
color: const Color(0xff2da162),
borderRadius: BorderRadius.all(
Radius.circular(50),
),
),
),
Card(
child: Padding(
padding: const EdgeInsets.all(5.0),
child: Text(
'${data.firstName.toString()}M',
style: TextStyle(
color: Colors.black,
fontWeight: FontWeight.w700,
fontFamily: "SFProText",
fontStyle: FontStyle.normal,
fontSize: 13.0,
),
),
),
),
],
),
),
);
}
}
What I want:
What I have:
What I ended up doing was removing the listview.builder all together and mapped the list in the markerPointers:[], so this is the result.
My LinearGauge:
Expanded(
flex: 4,
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Expanded(
child: SizedBox(
height: size.height * 0.57,
child: SfLinearGauge(
showLabels: false,
showTicks: false,
showAxisTrack: false,
orientation: LinearGaugeOrientation.vertical,
minimum: 0,
maximum: 100,
animationDuration: 500,
markerPointers: _sortedList
.asMap()
.map(
(i, data) {
return MapEntry(
i++,
LinearWidgetPointer(
value: data.points,
position: LinearElementPosition.cross,
animationDuration: 2000,
offset: 500,
child: UserCardWidget(
data: data,
index: i,
isExpandedMethod: _isExpanded,
),
),
);
},
)
.values
.toList(),
),
),
),
],
),
),
This is the result:
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();
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,
),
),
),
);
}
I am trying to use a dialog widget which will get some info from future builder, when I build the dialog under onTap it works but code looks so weird in that way because I use that build more then once, so I want to make a dialog class then call it when I needed but I couldn't achieve that yet, is this possible? My related code samples are below;
Code in the screen that I tried to call dialog box(homepage.dart):
void showCast() {
showDialog<void>(
context: context,
builder: (context){
return CastDialog();
}
);
}
#override
Widget build(BuildContext context) {
return FutureBuilder<Payload>(
...
...
...
child: GestureDetector(
child: Image.network(
snapshot.data
.movieCast[index]
.image != null
? "http://image.tmdb.org/t/p/w185" +
snapshot.data
.movieCast[index]
.image
: "http://image.tmdb.org/t/p/original/zUqyn3aQXTzeP1n8yd8Udt1twYA.jpg",
fit: BoxFit.contain,),
onTap: () async {
List<dynamic> castVar;
http.Response responseC = await http.get("http://lunedor.pythonanywhere.com/query?castid=${snapshot.data.movieCast[index].castID}&language=${AppLocalizations.of(context).translate('lan_code')}").timeout(const Duration(seconds: 10));
Map<String, dynamic> castV = jsonDecode(responseC.body);
castVar = castV['moviecastimages'];
print(castVar);
String nameC = (snapshot.data.movieCast[index]).toString();
String _movieCast = (snapshot.data.movieCast[index]).toString();
String _url = (snapshot.data.movieCast[index].castID).toString();
return
showCast();
},
),
Code for dialog(dialogs.dart):
class CastDialog extends StatefulWidget{
#override
_CastDialogState createState() => _CastDialogState();
}
class _CastDialogState extends State<CastDialog> {
String nameC;
String _movieCast;
String _url;
List castVar;
void initState() {
super.initState();
}
#override
Widget build(BuildContext context) {
return SimpleDialog(
title:
Row(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
SizedBox(
width: 20,
height: 20,
child: GestureDetector(
onTap: () async{
http.Response responseB = await http.get("https://api.themoviedb.org/3/person/$_url?api_key=1b8cfaea32775f684a7baff93bb1a3fc&language=${AppLocalizations.of(context).translate('lan_code')}").timeout(const Duration(seconds: 10));
Map<String, dynamic> castCB = jsonDecode(responseB.body);
return showDialog(context: context,
builder: (context) {
return SimpleDialog(
title: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
Text(nameC),
SizedBox(
width: 20,
height: 20,
child: GestureDetector(
onTap: (){ Navigator.pop(context);},
child: Icon(Icons.close)),
),
],
),
children: <Widget>[
Divider(
color: Colors.black.withOpacity(0.5),
height: 5,
thickness: 3,
),
Wrap(
children: <Widget>[
Padding(
padding: const EdgeInsets.all(8.0),
child: Container(
child: Text(castCB['biography'], style: TextStyle(fontSize: 14),),
),
),
],
),],
);
});
},
child: Icon(Icons.info)),
),
Text(_movieCast),
SizedBox(
width: 20,
height: 20,
child: GestureDetector(
onTap: (){ Navigator.pop(context);},
child: Icon(Icons.close)),
),
],
),
shape: RoundedRectangleBorder(borderRadius: new BorderRadius.circular(15.0)),
children: <Widget>[
Divider(
color: Colors.black.withOpacity(0.5),
height: 5,
thickness: 3,
),
Material(
child: Container(
width: 400,
height: 600,
child: new GridView.builder(
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 2,
childAspectRatio: 1.5 /
2.5,
),
itemCount: castVar.length,
itemBuilder: (context, index) {
return Column(
children: <
Widget>[
SizedBox(
height: 220,
child: Stack(
children: <Widget>[
Image.network(castVar[index]['poster'] != null ? "http://image.tmdb.org/t/p/w185" + castVar[index]['poster']
: "https://i.hizliresim.com/bbn0VB.jpg", fit: BoxFit.contain),
Container(
width: MediaQuery
.of(context)
.size
.width,
height: 220,
alignment: Alignment.bottomLeft,
padding: EdgeInsets.only(bottom: 5.0),
margin: const EdgeInsets.only(
left: 5.0),
child: new CircularPercentIndicator(
radius: 40.0,
lineWidth: 5.0,
percent: double.tryParse(
castVar[index]['vote'])/10,
center: Stack(
children: <Widget>[
Text(
castVar[index]['vote'],
style: TextStyle(
foreground: Paint()
..style = PaintingStyle.stroke
..strokeWidth = 3
..color = Colors.black,
),
),
new Text(castVar[index]['vote'],
style: TextStyle(
fontWeight: FontWeight.bold,
color: Colors.amber,),),
],
),
progressColor: Colors.amber,
)
),],
),
),
Text(castVar[index]['title'], maxLines: 1,
textAlign: TextAlign.center,
style: TextStyle(
fontSize: 14.0,
fontWeight: FontWeight.bold)
),
Text("(" + castVar[index]['year'] + ")", maxLines: 1,
textAlign: TextAlign.center,
style: TextStyle(
fontSize: 14.0,
fontWeight: FontWeight.bold,),
)
],
);
}),
),
),
],
);
}
}