Is there a way to handle double click in Flutter DataRow?

180 views Asked by At

today i was wondering if there is a way to handle the double click event in each row of a DataTable.

Does anyone knows?

EDIT: I tried by wrapping all the DataTable with InkWell but by doing this I wont be able to access the index/content of each row. This i s the code

    DataTable(
    onSelectAll: (val) {
        setState(() {
            selectedIndex = -1;
        });
    },      
    border: TableBorder.all(color: textColor),
    columnSpacing: 20,
    showCheckboxColumn: false,
    headingRowHeight: 32,
    headingRowColor: MaterialStateColor.resolveWith((states) => mainColor),
    dataRowMinHeight: 40,
    dataRowMaxHeight: 40,
    columns: const <DataColumn>[
        DataColumn(label: Text("Cognome", style: TextStyle(color: Colors.white),)),
        DataColumn(label: Text("Nome", style: TextStyle(color: Colors.white),)),
        DataColumn(label: Text("Email", style: TextStyle(color: Colors.white),)),
        DataColumn(label: Text("Telefono", style: TextStyle(color: Colors.white),)),
        DataColumn(label: Text("Ore/Sett", style: TextStyle(color: Colors.white))),
        DataColumn(label: Text("Disp./Sett", style: TextStyle(color: Colors.white))),
    ],
    rows: List<DataRow>.generate(
        snapshot.data!.length, (index) {
            return DataRow(

                color: MaterialStateProperty.resolveWith((states) {
                    if(states.contains(MaterialState.selected)) {
                        return accentColor50;
                    }
                    if(index % 2 == 0) {
                        return mainColor200;
                    }
                    return null;
                }),
                selected: index == selectedIndex,
                onSelectChanged: (value) {
                    setState(() {
                        selectedIndex = index;
                    });
                    context.read<GestioneDocentiProvider>().setSelectedRow(index);
                    context.read<GestioneDocentiProvider>().setDocenteSelezionato(snapshot.data![index]);
                    context.read<GestioneOrarioCompletoProvider>().setDocenteSelezionato(snapshot.data![index]);
                    context.read<GestioneDocentiProvider>().impostaSelezioneRiga();
                    context.read<GestioneOrarioCompletoProvider>().impostaOrario();
                },
                cells: <DataCell>[
                    DataCell(GestureDetector(child: Text(snapshot.data![index].cognome))),
                    DataCell(Text(snapshot.data![index].nome)),
                    DataCell(Text(snapshot.data![index].email)),
                    DataCell(Text(snapshot.data![index].telefono)),                                  
                    DataCell(Align(
                        alignment: Alignment.center,
                        child: Text(
                            snapshot.data![index].oreSettimanali, 
                            style: snapshot.data![index].oreSettimanali == "0"
                            ? TextStyle(color: Colors.red[400], fontWeight: FontWeight.bold)
                            : const TextStyle(color: textColor)))),
                    DataCell(Align(
                        alignment: Alignment.center,
                        child: Text(
                            snapshot.data![index].oreDoc, 
                            style: snapshot.data![index].oreDoc == "0"
                            ? TextStyle(color: Colors.red[400], fontWeight: FontWeight.bold)
                            : const TextStyle(color: textColor))))


                ],
            );
        })),
3

There are 3 answers

2
Munsif Ali On

wrap the widget with InkWell and there is a property named onDoubleTap with this you can achieve it like bellow

InkWell(
 onDoubleTap: (){},
)
1
Aprendendo Next On

You can use a Gesture detector with a double tap event:

        DataCell(
          GestureDetector(
            onDoubleTap: () {
              print('Ouch!');
            },
            child: Text('Double tap this'),
          ),
        ),
0
Aprendendo Next On

You can also make a little trick by checking if you selected it twice in a short amount of time:

import 'package:flutter/material.dart';

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        body: MyDataTable(),
      ),
    );
  }
}

class MyDataTable extends StatefulWidget {
  @override
  _MyDataTableState createState() => _MyDataTableState();
}

class _MyDataTableState extends State<MyDataTable> {
  DateTime? _lastRowTap;

  @override
  Widget build(BuildContext context) {
    return DataTable(
      columns: [
        DataColumn(label: Text('Name')),
        DataColumn(label: Text('Age')),
      ],
      rows: [
        customDataRow('Alice', '25'),
        customDataRow('Bob', '30'),
        customDataRow('Charlie', '35'),
      ],
    );
  }

  DataRow customDataRow(String name, String age) {
    return DataRow(
      cells: [
        DataCell(Text(name)),
        DataCell(Text(age)),
      ],
      onSelectChanged: (selected) {
        final now = DateTime.now();
        if (_lastRowTap != null &&
            now.difference(_lastRowTap!).inMilliseconds < 300) {
          print('Double tapped on $name');
        }
        _lastRowTap = now;
      },
      color: MaterialStateProperty.resolveWith<Color>(
        (Set<MaterialState> states) {
          if (states.contains(MaterialState.selected))
            return Theme.of(context).colorScheme.primary.withOpacity(0.08);
          return Colors.transparent;
        },
      ),
    );
  }
}