Haaselh0ff
Haaselh0ff

Reputation: 3

Flutter: Trying to highlight a ListTile using OnTap

I'm trying to figure out how to go about highlighting a selected ListTile so I only edit values of the highlighted Tiles from a Database.

Some contextual code in case it is needed.

User_List.dart

class UserList extends StatefulWidget {
  @override
  _UserListState createState() => _UserListState();
}

class _UserListState extends State<UserList> {
  @override
  Widget build(BuildContext context) {

    final users = Provider.of<List<Camper>>(context) ?? [];

    return ListView.builder(
      itemCount: users.length,
      itemBuilder: (context, index){
        return UserTile(user: users[index]);
      },
    );
  }
}

The below is the code that I'm trying to get the OnTap working on.

User_Tile.dart

class UserTile extends StatelessWidget {

  final Camper user;
  UserTile({this.user});

  @override
  Widget build(BuildContext context) {
    return Padding(
      padding: EdgeInsets.only(top: 8.0),
        child: Card(
          elevation: 10.0,
          color: Colors.blue[100],
          shape: RoundedRectangleBorder(
            borderRadius: BorderRadius.circular(10.0),
          ),
          margin: EdgeInsets.fromLTRB(20.0, 6.0, 20.0, 0.0),
          child: ListTile(
            leading: Text('ID: ${user.camperID}'),
            title: Text(user.name),
            subtitle: Text(user.instrument),
            //Dense compacts the text together more
            dense: true,
            trailing: Text(user.band + ' Band'),

          ),
        ),
    );
  }
}

Most of my attempts at using onTap or onPressed were failing and I am not experienced enough with Flutter so I thought I'd ask here and see if anyone knew.

If you need more information from me please let me know. Thanks.

Upvotes: 0

Views: 2276

Answers (3)

Mithson
Mithson

Reputation: 1782

The quickest way to do this is by wrapping your ListTile inside of ListView and giving with ListTile property onTap() as without it there will be no material ripple effect and also you need to make your Listview elements shrinkwrap by adding shrinkwrap: true so it takes only required space n doesn't take all the space and you can give each of the ListTile item an ink property which can take different colors whichever you want. I know its too late for an answer but this is simplest way to do so which may help others,

try the code below,

ListView( shrinkWrap: true,
              children: <Widget>[
                ListTile(
                  onTap: () {},
                  leading: Icon(
                    Icons.home,
                    color: Colors.black,
                  ),
                  title: Text('Home'),
                ),],
            ),

Upvotes: 0

Aamil Silawat
Aamil Silawat

Reputation: 8229

Use statefulwidget instead of statelesswidget

class UserList extends StatefulWidget {
  @override
  _UserListState createState() => _UserListState();
}

class _UserListState extends State<UserList> {
  @override
  Widget build(BuildContext context) {

    int selectedIndex = 0;
    final users = Provider.of<List<Camper>>(context) ?? [];

    return ListView.builder(
      itemCount: users.length,
      itemBuilder: (context, index){
        return Padding(
          padding: EdgeInsets.only(top: 8.0),
          child: Card(
            elevation: 10.0,
            color: Colors.blue[100],
            shape: RoundedRectangleBorder(
              borderRadius: BorderRadius.circular(10.0),
            ),
            margin: EdgeInsets.fromLTRB(20.0, 6.0, 20.0, 0.0),
            child: Container(
              child: ListView.builder(
                  padding: EdgeInsets.only(left: 10.0),
                  itemCount: users.length,
                  itemBuilder: (BuildContext context, int index) {
                    return GestureDetector(
                      onTap: () {
                        setState(() {
                          selectedIndex = index;
                        });
                      },
                      child: ListTile(
                        leading: Text('ID: ${users.camperID}'),
                        title: Text(users.name,style: TextStyle(
                            color: index == selectedIndex
                                ? Colors.white
                                : Colors.white60,
                            fontWeight: FontWeight.bold,
                            fontSize: 24.0,
                            letterSpacing: 1.2),),
                        subtitle: Text(users.instrument),
                        //Dense compacts the text together more
                        dense: true,
                        trailing: Text(users.band + ' Band'),
                      ),
                    );
                  }
              ),
            ),
          ),
        );
      },
    );
  }
}

Upvotes: 1

JMo
JMo

Reputation: 101

Have you tried wrapping it in a gesturedetector?

Upvotes: 0

Related Questions