Handle Grid list view with add button in flutter

Viewed 190

I want view like that , grid list will be dynamic but addButton should be stick with it's position. like below image:

enter image description here

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:

enter image description here

Run this code on dartPad

1 Answers

One way you can do this is like so.

GridView.builder(
             itemCount: itemCount + 1,
             gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(crossAxisCount: 4),
             itemBuilder: (BuildContext context, int index) {
               if (index == itemCount)
                 return AddUserButton(onAdduser: addUser);

               return Column(
                 mainAxisAlignment: MainAxisAlignment.center,
                 children: [
                   SelectedUserTile(onRemoveUser: removeUser),
                   Text("Group Name", style: TextStyle(fontSize: 10))
                 ],
               );
             })
Related