Flutter: Horizontal auto Scrolling - flutter

I would like some help with getting the artist names to automatically scroll from right to left (or left to right if that's easier for you) in flutter, but I am not sure how to go about that and would appreciate someone's help :) I have looked into Horizontal ListViews and all but I was getting errors so I didn't move forward with that.
#override
Widget build(BuildContext context) {
return Scaffold(body: Stack(
children: <Widget>[
Container(decoration: BoxDecoration(
image: DecorationImage(
image: AssetImage("assets/images/danceClub.jpg"),
fit: BoxFit.cover,
),
),
child: BackdropFilter(
filter: ImageFilter.blur(sigmaX: 5.0, sigmaY: 5.0),
child: Container(decoration: BoxDecoration(color: Colors.black.withOpacity(0.2))))
),
Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Center(child: Container(child: Text('Now Playing', style: TextStyle(fontSize: 30, color: Colors.black),),)),
_imageURLValue != null ? Image.network(_imageURLValue, height: 300) : Container(),
Row(mainAxisSize: MainAxisSize.max, children: <Widget>[Padding(padding: EdgeInsets.only(left: 30.0)), Text('${_songName}', style: TextStyle(fontSize: 25, color: Colors.amber)), Text(' - ', style: TextStyle(fontSize: 25, color: Colors.black)),
Expanded(child: ListView.builder(shrinkWrap: true, itemCount: _artistsNames == null ? 0 : _artistsNames.length,
itemBuilder: (context, i) { return Text(_artistsNames[i], style: TextStyle(fontSize: 25, color: Colors.blue),);}))]),
Container(child: RaisedButton(
onPressed: () => Navigator.pop(context),
child: Text('Exit to menu'),
)),
Container(child: RaisedButton(
onPressed: getData,
child: Text('Get data from http!', style: TextStyle(color: Colors.white, fontStyle: FontStyle.italic, fontSize: 20.0)),
))
],
)
]
)
);
}
}

There is a Flutter plugin that seems to match exactly your need:
marquee:
https://pub.dev/packages/marquee
A Flutter widget that scrolls text infinitely. Provides many customizations including custom scroll directions, durations, curves as well as pauses after every round.

The most simple solution is to use carousel_slider library

Related

I want to right justify the TextButton in Flutter

I want to send the "See More" button in the middle to the right.
Row(
children: <Widget>[
Stack(
children: const <Widget>[
Align(
alignment: Alignment.topLeft,
child: Padding(
padding: EdgeInsets.all(8.0),
child: Text(
'Your Watchlist',
style: TextStyle(
color: Colors.white,
fontSize: 20,
fontWeight: FontWeight.bold,
),
),
),
),
],
),
TextButton(
child: const Text(
'See More >>',
style: TextStyle(color: Colors.yellow, fontSize: 16),
),
onPressed: () {
Navigator.of(context).push(MaterialPageRoute(
builder: (context) => movie_list(),
));
},
),
],
),
Also, how can I pull data from firebase to listview items in the form of cards at the bottom, can you suggest a source on this subject?
You can achieve this by 2 methods
Option1
Add
mainAxisAlignment: MainAxisAlignment.spaceBetween,
To the row widget
Or
Option2
add
Spacer()
Between the see more and the stack widget
You can include Spacer() on middle portion,
Row
- WidgetA
- Spacer()
- WidgetB

How can I change the width of a container/card depending on screen size?

I tried adding a width to the container but it didn't do anything. By default it fills the page? Not sure what's happening. Do I have to use MediaQuery somewhere? I want the post to be the same size on both the phone and the tablet. I'm not great with explaining so I added a photo to help.
Here's my code:
body: ListView(
children: [
Container(
height: 132,
decoration: BoxDecoration(borderRadius: BorderRadius.circular(15)),
child: Card(
margin: EdgeInsets.all(10),
elevation: 8,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(15)),
child: Column(
children: <Widget>[
ListTile(
leading: CircleAvatar(
backgroundColor: Color(0xFF192A4F),
),
title: SizedBox(
height: 39,
child: TextButton(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
AutoSizeText(
'Username',
style: TextStyle(
color: Color(0xFF192A4F),
fontSize: 16,
fontWeight: FontWeight.bold),
maxLines: 2,
overflow: TextOverflow.ellipsis,
),
],
),
style: TextButton.styleFrom(
padding: EdgeInsets.zero,
minimumSize: Size(50, 30),
alignment: Alignment.centerLeft),
onPressed: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => SeventhRoute(),
),
);
},
),
),
),
Divider(
height: 10,
color: Colors.black26,
),
Row(
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: <Widget>[
Row(
children: <Widget>[
Icon(Icons.comment_outlined,
color: Colors.black),
SizedBox(width: 8.0),
Text(
'Comment',
style: TextStyle(color: Colors.black),
),
],
),
Row(
children: <Widget>[
Icon(Icons.bookmark_outline, color: Colors.black,),
SizedBox(width: 8.0),
Text('Bookmark', style: TextStyle(color: Colors.black),),
],
),
],
),
SizedBox(
height: 12.0,
)
],
),
),
),
],
),
double width = MediaQuery.of(context).size.width;
you can get screen width from here. Then add a logic
As example if screen width of right phone is 500 and left is 1000,
then you can set
if the screen width is <= 500 ,
set the container width as screen width
otherwise
set the container width as 500.
---Additionally---
You can get screen orientation like this
var isPortrait = MediaQuery.of(context).orientation == Orientation.portrait
The reason specifying the width is ignored is because you didn't specify what should happen with the smaller card. The framework doesn't know if it should be aligned left, center, right, etc. To fix this, you can wrap your Card, Container, or even the whole ListView in a Center (or Align) widget.
Based on your images i can see that only the width is changing, height is constant, so i'd suggest in your container give width: MediaQuery.of(context).size.width;
And of course some padding to that container.
It looks like you want that widget to take as much width as it can, but no more than 500px wide. Trivial:
ConstrainedBox(
child: YourChild(...),
constraints: BoxConstraints(maxWidth: 500),
),

Updating single item on a Listview.builder widget in Flutter

so I have a list of users that is in a Listview.builder widget but my issue is that when I try to update one item on the list all the other items update as well.
I have a button that shows "Add friend" when I click on the button the message should change to "Invited", I have a string variable that holds the message so when I click on the button the string is updated from "Add friend" to "Invited", now when I click on button all the other button values change as well.
Here is my code:
class Friends extends StatefulWidget{
_FriendsState createState() => _FriendsState();
}
class _FriendsState extends State<Friends>{
List<String> nameList = [];
String btnText;
#override
Widget build(BuildContext context) {
bool showFriendList = false;
return Scaffold(
appBar: AppBar(
title: Text('Friends'),
actions: <Widget>[
IconButton(
onPressed: (){
},
icon: Icon(Icons.check, color: Colors.white,),
)
],
),
body:
Padding(
padding: EdgeInsets.all(10),
child: ListView(
children: <Widget>[
showFriendList? Column(
children: <Widget>[
Text('Find friends to add. Once they accept you can invite them to your challenge.', style: TextStyle(fontWeight: FontWeight.w500, fontSize: 16),),
SizedBox(height: 45,),
Container(
width: MediaQuery.of(context).size.width,
child: RaisedButton(
child: Text('GO AND FIND FRIENDS', style: TextStyle(fontWeight: FontWeight.w500, fontSize: 14, color: Colors.white)),
onPressed: (){
setState(() {
showFriendList != showFriendList;
});
},
color: Theme.of(context).accentColor,
shape: RoundedRectangleBorder(side: BorderSide(color: Theme.of(context).accentColor),borderRadius: BorderRadius.circular(14)),
),
)
],
): Container(
height: MediaQuery.of(context).size.height,
child:friends(context) ,
)
],
) ,
)
);
}
Widget friends(BuildContext context){
return
ListView(
children: <Widget>[
Container(
margin: EdgeInsets.all(8),
padding: EdgeInsets.all(8),
decoration: BoxDecoration(
color: Colors.white
),
child: TextField(
decoration:InputDecoration(
hintText: 'Enter User\'s name',
border: InputBorder.none,),
),
),
/* noRequest== true? SizedBox(height: 0,):friendRequest(context),
noRequest== true? SizedBox(height: 0,): Container(
margin: EdgeInsets.all(10),
height: 60,
child: Column(mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment:CrossAxisAlignment.start,
children: <Widget>[Text('Your friends', style: TextStyle(fontSize: 16, color: Theme.of(context).textSelectionColor,)) ],),
),*/
Container(
height: 0.5,
color: Colors.grey,
),
ListView.builder(
shrinkWrap: true,
itemCount: users.length,
itemBuilder: (BuildContext context, int index){
return
Container(
padding: EdgeInsets.only(left: 6),
height:80 ,
child:
Column(
children: <Widget>[
Row(
children: <Widget>[
users[index].profileUrl != null? CircleAvatar(child: Image.asset(users[index].profileUrl),): Container(
width: 50,
height: 50,
decoration: BoxDecoration(
color: Colors.white70,
shape: BoxShape.circle,
image: DecorationImage(
image:AssetImage('assets/plus.png') //NetworkImage(renderUrl ??'assets/img.png')
)
),
),
SizedBox(width: 30,),
Expanded(
flex: 1,
child:
Container(
child:
Row(
children: <Widget>[
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
SizedBox(height: 12,),
users[index].fullName != null? Text( users[index].fullName, style: TextStyle(fontSize: 18)): Text('Anjelika Thompson', style: TextStyle(fontSize: 18),),
SizedBox(height: 12,),
Row(
//crossAxisAlignment: CrossAxisAlignment.start,
// mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
Container(child: Icon(Icons.location_on),alignment: Alignment.topLeft,),
SizedBox(width: 10,),
users[index].distance_KM.toString() != null ? Text( users[index].distance_KM.toString()):Text('48.7 km')
]),
],
),
],
)
),
),
SizedBox(width: 0,),
//Icon(Icons.check,color: Colors.red,size: 40,)
FlatButton(
child: Text(btnText==null? 'ADD FRIEND': btnText, style: TextStyle(color: Color(0xff7667e5)),),
onPressed: () {
nameList.add(users[index].fullName);
setState(() {
btnText = 'INVITED';
});
},
)
],
),
Container(
height: 0.5,
color: Colors.grey,
)
],
) ,
);
}
// final item = feeds[index];
)
],
);
}
}
From my class, I have a string value called "btnText" that I use to set the new value. but at the moment once I click on one button to change from "Add friend" to "Invited" all other button Text in the listview change as well.
Please I need help figuring out what is the problem
#Chidinma, you can add a check to see if user is in your nameList,
FlatButton(
child: Text(btnText==null || !nameList.contains(users[index].fullName) ? 'ADD FRIEND': btnText, style: TextStyle(color: Color(0xff7667e5)),),
onPressed: () {
nameList.add(users[index].fullName);
setState(() {
btnText = 'INVITED';
});
................
This is just to give you an idea. A better solution would be to create a selected column in users table and save selected state as bool value. If you don't have database then i'd recommend creating indexList like nameList and save the index of invited friends and check to see if index is in the indexList like i've done with the nameList instead.
Method
inviteButtonStateFunction(index){
for (var e in invitedPeopleListIndex) {
if(e == index){
return Text("Invited");
}
}
return Text("Invite");
}
Usage
child: TextButton(
onPressed: () {
if(invitedPeopleListIndex.contains(index)){
invitedPeopleListIndex.remove(index);
}else{
invitedPeopleListIndex.add(index);
}
print(invitedPeopleListIndex);
print(invitedPeopleList);
},
child: inviteButtonStateFunction(index), // Show the text here
)

Flutter nested GestureDetector doesn't work

everyone! I have a list of items. The main Widget in the list is Card. I wanna wrap it in a GestureDetector to catch tap event on a whole card. I also have Stack inside the card where I have bookmark icon. I am trying to wrap this icon into GestureDetector but it doesn't work.
My item:
#override
Widget build(BuildContext context) {
// TODO: implement build
return Card(
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(8.0)),
child: Column(
children: <Widget>[
Stack(
children: <Widget>[
ClickableIcon(_model._bookmarked),
Container(
height: 128.0,
constraints: BoxConstraints(minWidth: double.infinity),
child: Image.network(_model._headerSource),
),
],
),
Container(
height: 72,
constraints: BoxConstraints(minWidth: double.infinity),
child: Row(
children: <Widget>[
Container(
margin: const EdgeInsets.only(left: 16.0, right: 16.0),
child: CircleAvatar(
radius: 20.0,
backgroundImage: NetworkImage(_model._organizerLogo),
backgroundColor: Colors.transparent,
),
),
Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
_model._eventName,
style: TextStyle(
fontSize: 15,
color: Colors.black,
fontWeight: FontWeight.w500),
textAlign: TextAlign.start,
),
SizedBox(
height: 8,
),
Text(
"${_model._timeStart} ${_model._guide}",
style: TextStyle(
fontSize: 12,
color: Color(GoEngColors.secondaryTextColor),
fontWeight: FontWeight.w500),
)
])
],
),
)
],
),
);
}
Clickable icon code:
class _ClickableIconState extends State<ClickableIcon> {
#override
Widget build(BuildContext context) {
// TODO: implement build
return InkWell(
onTap: () {
print("bookmarked");
setState(() {
print("state updated");
widget.selected = !widget.selected;
});
},
child: Container(
child: Icon(widget.selected
? CustomIcon.MyFlutterApp.icon_mark_applouded_1
: CustomIcon.MyFlutterApp.icon_mark_empty_1),
alignment: Alignment.topRight,
),
);
}
}
I tried both GestureDetector and InkWell but none of them gave an expected result. I also tried to set a behaviour for a GestureDetector, but it didn't help as well.
So my question is as follows: how to make icon clickable remaining click implementation for the whole card? Thanks!
EDIT
Using IconButton instead of Icon didn't help.
I think your stack order need to be reversed
Stack(
children: <Widget>[
Container(
height: 128.0,
constraints: BoxConstraints(minWidth: double.infinity),
child: Image.network(_model._headerSource),
),
ClickableIcon(_model._bookmarked),
],
),
please, test and let me know if it worked for you.

How to remove the space between rows in card (Flutter)

I used a card widget in my flutter App that has two rows, the problem that I have is a large space appeared between the two rows as you can see in the following image
how can fix this problem ?
my code that i tried it here :
return Card(
child: Container(
alignment: FractionalOffset.center,
child: Row(
children: <Widget>[
Expanded(
flex: 1,
child: Container(
child: ListTile(
title: Text(snapshot.data[index].data["title"],
textDirection: TextDirection.rtl,
style: TextStyle(fontSize: 14.0,
fontFamily: 'Cairo',
fontWeight: FontWeight.bold),),
onTap: () => navigateToDetails(snapshot.data[index]),
),
),
),
//SizedBox(width: 1.0),
Expanded(
flex: 1,
child: Container(child: Image.network(snapshot.data[index].data["image_url"],height: 80.0,width: 80.0)),
),
],
),
),
);
add MainAxisAlignment:MainAxisAlignment.center property to your Row widget
followed code should work for you check this out.
return Card(
child: Container(
alignment: FractionalOffset.center,
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Expanded(
flex: 1,
child: Container(
child: ListTile(
title: Text(
snapshot.data[index].data["title"],
textDirection: TextDirection.rtl,
style: TextStyle(
fontSize: 14.0,
fontFamily: 'Cairo',
fontWeight: FontWeight.bold),
),
onTap: () => navigateToDetails(snapshot.data[index]),
),
),
),
//SizedBox(width: 1.0),
Expanded(
flex: 1,
child: Container(
child: Image.network(snapshot.data[index].data["image_url"],
height: 80.0, width: 80.0)),
),
],
),
),
);
you are using expanded widget inside row so that both the widget try to get same width and also try to cover whole width possible.
so that, if you want to remove space between row widget then remove expanded widget and play with MainAxisAlignment property of Row to arrange or manage the space.
you can use values like:
MainAxisAlignment.spaceBetween and MainAxisAlignment.spaceEvenly