creativecreatorormaybenot
creativecreatorormaybenot

Reputation: 126734

How to make onTap only respond on Actual Text not whole ListTile width

Illustrations

I have the following problem:

ListTile

The title and subtitle components of ListTile expand fully even when there only is text in some smaller area.
Usually, this is not a problem as you could just color the background of the title the same as the ListTie.

However, I have a problem when trying to get an onTap event working on a Row in title or subtitle:

ListTile onTap

As you can see, I have a Row in the title component with an Icon and a Text. That works fine, however, trying to add an onTap to this title will produce unwanted behavior.
I only want the onTap to trigger when I actually tap the text or icon and not when I tap somewhere else to the right. I am clueless how I would constrain the width of the title to the width of the text plus icon. It seems like nothing works. What is going on here?

Code

I created a Gist with the source code (minimal reproducible example) for both illustrations. This should help to give you an idea of the setup.

How do I only trigger onTap when the actual children of the Row are tapped and not the whole title area that apparently expands no matter what I do?

Notes

I could probably just add an InkWell to both the Text and the Icon individually, however, that is not at all what I want because I want a splash (InkWell's splash) to cover the title and icon together and they should not be visually seperated.

Upvotes: 3

Views: 990

Answers (2)

shb
shb

Reputation: 6277

Use FlatButton.icon instead of using InkWell and Row.

FlatButton.icon solves your mentioned problem and serves both of your purpose to have splash effect and a Title with Icon. It reduces your code too. See below for example

title: Align(
     alignment: Alignment.centerLeft,
     heightFactor: 1.0,
     child: FlatButton.icon(
         splashColor: Colors.white,
         onPressed: () {},
         icon: Icon(Icons.format_align_left),
         label: Text('title'))),

Full code

main() {
  runApp(
    MaterialApp(
      home: Scaffold(
        body: Center(
          child: Container(
            color: Colors.greenAccent,
            child: ListTile(
              dense: true,
              leading: Material(child: const Text('leading')),
              title: Material(
                child: Align(
                    alignment: Alignment.centerLeft,
                    heightFactor: 1.0,
                    child: FlatButton.icon(
                        splashColor: Colors.white,
                        onPressed: () {},
                        icon: Icon(Icons.format_align_left),
                        label: Text('title'))),
              ),
              subtitle: Material(child: const Text('subtitle')),
              trailing: Material(child: const Text('trailing')),
            ),
          ),
        ),
      ),
    ),
  );
}

Upvotes: 1

Saed Nabil
Saed Nabil

Reputation: 6861

Please, try this code it works for me

import 'package:flutter/material.dart';
main() {
  runApp(
    MaterialApp(
      home: Scaffold(
        body: Center(
          child: Container(
            color: Colors.greenAccent,
            child: ListTile(
              dense: true,
              leading: Material(child: const Text('leading')),
              title: Material(
                child: Row(
                  children: <Widget>[
                    InkWell(
                      onTap: () {},
                      child: Row(
                        mainAxisSize: MainAxisSize.min,
                        children: <Widget>[
                          Icon(Icons.format_align_left),
                          Text(
                            'title',
                          ),
                        ],
                      ),
                    ),

                      Container(
                        height: 0.0,
                      ),

//                    Expanded(child: Container(
//                      height: 10.0,
//                    ),)
                  ],
                ),
              ),
              subtitle: Material(child: const Text('subtitle')),
              trailing: Material(child: const Text('trailing')),
            ),
          ),
        ),
      ),
    ),
  );
}

Upvotes: 3

Related Questions