I want view like that , grid list will be dynamic but addButton should be stick with it's position. like below image:
i have tried but not able to handle add button within list:
code:
class Demo extends StatefulWidget {
@override
_DemoState createState() => _DemoState();
}
class _DemoState extends State<Demo> {
int itemCount =1;
addUser(){
setState(() {
itemCount ++;
});
}
removeUser(){
if(itemCount>1){
setState(() {
itemCount --;
});
}
}
@override
Widget build(BuildContext context) {
final size = MediaQuery.of(context).size;
return SafeArea(
child: Scaffold(
body: Container(
padding: const EdgeInsets.all(10),
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.only(
topLeft: Radius.circular(30),
topRight: Radius.circular(30),
)
),
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Padding(
padding: const EdgeInsets.only(left:15.0),
child: Text("Participants",
style: TextStyle(
fontSize: 20,
fontWeight: FontWeight.bold,
color: Colors.blueGrey),),
),
Container(
padding: const EdgeInsets.only(top: 8),
height: size.height * 0.7,
child: GridView.builder(
itemCount: itemCount,
gridDelegate:
SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 4),
itemBuilder: (BuildContext context, int index) {
return Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
SelectedUserTile(
onRemoveUser:removeUser
),
Text("Group Name" , style: TextStyle(
fontSize: 10
),)
],
);
}),
),
AddUserButton(
onAdduser:addUser
),
Align(
alignment: Alignment.bottomCenter,
child: Container(
width: double.infinity,
child: FlatButton(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(80),
),
child: Text('CONTINUE', style: TextStyle(fontSize: 24)),
onPressed: () => {},
color: Theme.of(context).primaryColor,
textColor: Colors.white,
),
),
),
],
)
),
)
);
}
}
Selected user with remove button:
class SelectedUserTile extends StatelessWidget {
final Function() onRemoveUser;
const SelectedUserTile({Key key, this.onRemoveUser}) : super(key: key);
@override
Widget build(BuildContext context) {
return Container(
height: 60,
width: 65,
child: Stack(
children: [
UserAvatar(
avatarSize: 55,
image: "https://upload.wikimedia.org/wikipedia/commons/8/8d/Foto_Michele_Morrone.png",
),
Positioned(
top: 0,
right: 0,
child:InkWell(
onTap: onRemoveUser,//onDeselect
child: Card(
color: Colors.grey[400],
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(80),
),
elevation: 5,
child: Container(
alignment: Alignment.center,
height: 18,
width: 18,
decoration: BoxDecoration(),
child: Icon(
Icons.clear,
size: 15,
color: Colors.blueGrey,
),
),
),
) )
],
)
);
}
}
UserAvatar :
class UserAvatar extends StatelessWidget {
final String image;
final double avatarSize;
const UserAvatar({Key key, this.image, this.avatarSize}) : super(key: key);
@override
Widget build(BuildContext context) {
// final size = MediaQuery.of(context).size;
return Container(
height: avatarSize,
width: avatarSize,
decoration: BoxDecoration(
shape: BoxShape.circle, border: Border.all(color: Colors.grey)),
child: image != null
? Container(
margin: const EdgeInsets.all(2),
height:30,
width: 30,
// size.height * 0.35,
decoration: BoxDecoration(
shape: BoxShape.circle,
image: DecorationImage(
image: NetworkImage(image), fit: BoxFit.cover)),
)
: Container(
alignment: Alignment.center,
margin: const EdgeInsets.all(2),
height: 30,
decoration: BoxDecoration(
shape: BoxShape.circle,
color: Colors.white,
),
child: Icon(Icons.image)),
);
}
}
Add User Button
class AddUserButton extends StatelessWidget {
final void Function() onAdduser;
const AddUserButton({Key key, this.onAdduser}) : super(key: key);
@override
Widget build(BuildContext context) {
return InkWell(
onTap:onAdduser,
child: Container(
alignment: Alignment.center,
height: 55,
width: 55,
decoration: BoxDecoration(
shape: BoxShape.circle,
color: Colors.blueGrey,
),
child: Icon(Icons.add,
size: 30,
color:Colors.white)
),
);
}
}
Result:
Run this code on dartPad

