Flutter longPress event functionality for selection of row(s) and/or elements

3,962

You can use a HashMap to track the selected items in the List and update its values depending on the gesture that you'd like.

Here's a sample that you can try. In this sample, multi-select mode will start on long press of an item. Multi-select mode will stop when there's no selected items left.

import 'package:flutter/material.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
        visualDensity: VisualDensity.adaptivePlatformDensity,
      ),
      home: MyHomePage(title: 'Flutter Demo Home Page'),
    );
  }
}

class MyHomePage extends StatefulWidget {
  MyHomePage({Key key, this.title}) : super(key: key);

  final String title;

  @override
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  var selectMode = false;

  Map<String, bool> listItemSelected = {
    'List 1': false,
    'List 2': false,
    'List 3': false,
    'List 4': false,
    'List 5': false,
    'List 6': false,
    'List 7': false,
    'List 8': false,
    'List 9': false,
  };

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(widget.title),
      ),
      body: Center(
        child: ListView(
          children: listItemSelected.keys.map((key) {
            return Card(
              child: GestureDetector(
                onTap: () {
                  // if multi-select mode is true, tap should select List item
                  if (selectMode && listItemSelected.containsValue(true)) {
                    debugPrint('onTap on $key');
                    setState(() {
                      listItemSelected[key] = !listItemSelected[key];
                    });
                  } else {
                    // Stop multi-select mode when there's no more selected List item
                    debugPrint('selectMode STOP');
                    selectMode = false;
                  }
                },
                // Start List multi-select mode on long press
                onLongPress: () {
                  debugPrint('onLongPress on $key');
                  if (!selectMode) {
                    debugPrint('selectMode START');
                    selectMode = true;
                  }
                  setState(() {
                    listItemSelected[key] = !listItemSelected[key];
                  });
                },
                child: Container(
                  // Change List item color if selected
                  color: (listItemSelected[key])
                      ? Colors.lightBlueAccent
                      : Colors.white,
                  padding: EdgeInsets.all(16.0),
                  child: Text(key),
                ),
              ),
            );
          }).toList(),
        ),
      ),
    );
  }
}

Demo

demo

Share:
3,962
Ore0D3v
Author by

Ore0D3v

Updated on December 04, 2022

Comments

  • Ore0D3v
    Ore0D3v over 1 year

    I need to implement a long press selection on a row element of Flutter for Android and iOS. Any help please?

    My code so far:

    class ListElement extends StatelessWidget {
      ListElement({this.text, this.name, this.mId, this.animationController});
    
      final String text;
      final String name;
      final String mId;
      final AnimationController animationController; 
    
      @override
      Widget build(BuildContext context) {
        return new GestureDetector(
          onTap: () {
             Navigator.of(context).push(
                      new MaterialPageRoute(builder: (BuildContext context) => new DrugProfile(drugmId))
                    );
          }, 
          onLongPress: () {
           //HERE I NEED TO SELECT MULTIPLE ROWS IF IT FIRES
          }, 
    
          child: new SizeTransition(
            sizeFactor: new CurvedAnimation(
                parent: animationController, curve: Curves.easeOut),
            axisAlignment: 0.0,
            child: new Container(
              margin: const EdgeInsets.symmetric(vertical: 10.0),
              child: new Row(
                crossAxisAlignment: CrossAxisAlignment.start,
                children: <Widget>[
                  new Container(
                    margin: const EdgeInsets.only(right: 16.0),
                    child: new CircleAvatar(child: new Text(name[0].toUpperCase())),
                  ),
                  new Expanded(
                    child: new Column(
                      crossAxisAlignment: CrossAxisAlignment.start,
                      children: <Widget>[
                        new Text(name, style: Theme.of(context).textTheme.subhead),
                        new Container(
                          margin: const EdgeInsets.only(top: 5.0),
                          child: new Text(
                            text,
                            textAlign: TextAlign.left,
                            style: new TextStyle(
                            fontSize: 13.0,),
                          ),
                        ),
                      ],
                    ),
                  ),
                ],
              ),
            )
          )
        );
      }
    }
    

    Maybe I am wrong starting from the onLongPress event, but I need to do the following: If longPress on a row element then provide the ability to select many rows. And after selection then perform custom operation on the rows (this is not part of the question :) ) After selection I imagine a array of indexes that I can pass into a function for further processes. I only need help with multiple selection of elements.