Swipe List Item for more options (Flutter)

后端 未结 4 1319
谎友^
谎友^ 2020-12-22 19:17

Somedays ago I decided to choose an Ui for an app from Pinterest to practice building apps with Flutter but I\'m stuck with the Slider which shows an \"more\" and \"delete\"

相关标签:
4条回答
  • 2020-12-22 19:39
    Padding(
            padding: const EdgeInsets.all(8.0),
            child: ListView.builder(
                itemCount: the_length_of_your_items,
                itemBuilder: (BuildContext context,int index) {
                  return Slidable(
                    actionPane: SlidableDrawerActionPane(),
                    actionExtentRatio: 0.25,
                    child: Container(
                      color: Colors.white,
                      child: ListTile(
                        leading: Text(('the_leading')),
                        title: Text(('the_title')),
                        trailing: Text(('the_trailing')),
                        subtitle: Text(('the_subtitle')),
                      ),
                    ),
                    actions: <Widget>[
                      IconSlideAction(
                         caption: 'Archive',
                        color: Colors.blue,
                        icon: Icons.archive,
                        onTap: () {print('archive');},
                      ),
                      IconSlideAction(
                        caption: 'Share',
                        color: Colors.indigo,
                        icon: Icons.share,
                        onTap: () {print('share');},
                      ),
                    ],
                    secondaryActions: <Widget>[
                      IconSlideAction(
                        caption: 'More',
                        color: Colors.black45,
                        icon: Icons.more_horiz,
                        onTap: ()  {print('more');},
                      ),
                      IconSlideAction(
                        caption: 'Delete',
                        color: Colors.red,
                        icon: Icons.delete,
                        onTap: () {print('delete');},
                      ),
                    ],
                  );
                }),
          ),
    
    0 讨论(0)
  • 2020-12-22 19:40

    I have a task that needs the same swipeable menu actions I tried answeres of Romain Rastel and Rémi Rousselet. but I have complex widget tree. the issue with that slideable solutions is they go on other widgets(to left widgets of listview). I found a batter solution here someone wrote a nice article medium and GitHub sample is here.

    0 讨论(0)
  • 2020-12-22 19:41

    I created a package for doing this kind of layout: flutter_slidable (Thanks Rémi Rousselet for the based idea)

    With this package it's easier to create contextual actions for a list item. For example if you want to create the kind of animation you described:

    You will use this code:

    new Slidable(
      delegate: new SlidableDrawerDelegate(),
      actionExtentRatio: 0.25,
      child: new Container(
        color: Colors.white,
        child: new ListTile(
          leading: new CircleAvatar(
            backgroundColor: Colors.indigoAccent,
            child: new Text('$3'),
            foregroundColor: Colors.white,
          ),
          title: new Text('Tile n°$3'),
          subtitle: new Text('SlidableDrawerDelegate'),
        ),
      ),
      actions: <Widget>[
        new IconSlideAction(
          caption: 'Archive',
          color: Colors.blue,
          icon: Icons.archive,
          onTap: () => _showSnackBar('Archive'),
        ),
        new IconSlideAction(
          caption: 'Share',
          color: Colors.indigo,
          icon: Icons.share,
          onTap: () => _showSnackBar('Share'),
        ),
      ],
      secondaryActions: <Widget>[
        new IconSlideAction(
          caption: 'More',
          color: Colors.black45,
          icon: Icons.more_horiz,
          onTap: () => _showSnackBar('More'),
        ),
        new IconSlideAction(
          caption: 'Delete',
          color: Colors.red,
          icon: Icons.delete,
          onTap: () => _showSnackBar('Delete'),
        ),
      ],
    );
    
    0 讨论(0)
  • 2020-12-22 19:48

    There's already a widget for this kind of gesture. It's called Dismissible.

    You can find it here. https://docs.flutter.io/flutter/widgets/Dismissible-class.html

    EDIT

    If you need the exact same transtion, you'd probably have to implement if yourself. I made a basic example. You'd probably want to tweak the animation a bit, but it's working at least.

    class Test extends StatefulWidget {
      @override
      _TestState createState() => new _TestState();
    }
    
    class _TestState extends State<Test> {
      double rating = 3.5;
    
      @override
      Widget build(BuildContext context) {
        return new Scaffold(
          body: new ListView(
            children: ListTile
                .divideTiles(
                  context: context,
                  tiles: new List.generate(42, (index) {
                    return new SlideMenu(
                      child: new ListTile(
                        title: new Container(child: new Text("Drag me")),
                      ),
                      menuItems: <Widget>[
                        new Container(
                          child: new IconButton(
                            icon: new Icon(Icons.delete),
                          ),
                        ),
                        new Container(
                          child: new IconButton(
                            icon: new Icon(Icons.info),
                          ),
                        ),
                      ],
                    );
                  }),
                )
                .toList(),
          ),
        );
      }
    }
    
    class SlideMenu extends StatefulWidget {
      final Widget child;
      final List<Widget> menuItems;
    
      SlideMenu({this.child, this.menuItems});
    
      @override
      _SlideMenuState createState() => new _SlideMenuState();
    }
    
    class _SlideMenuState extends State<SlideMenu> with SingleTickerProviderStateMixin {
      AnimationController _controller;
    
      @override
      initState() {
        super.initState();
        _controller = new AnimationController(vsync: this, duration: const Duration(milliseconds: 200));
      }
    
      @override
      dispose() {
        _controller.dispose();
        super.dispose();
      }
    
      @override
      Widget build(BuildContext context) {
        final animation = new Tween(
          begin: const Offset(0.0, 0.0),
          end: const Offset(-0.2, 0.0)
        ).animate(new CurveTween(curve: Curves.decelerate).animate(_controller));
    
        return new GestureDetector(
          onHorizontalDragUpdate: (data) {
            // we can access context.size here
            setState(() {
              _controller.value -= data.primaryDelta / context.size.width;
            });
          },
          onHorizontalDragEnd: (data) {
            if (data.primaryVelocity > 2500)
              _controller.animateTo(.0); //close menu on fast swipe in the right direction
            else if (_controller.value >= .5 || data.primaryVelocity < -2500) // fully open if dragged a lot to left or on fast swipe to left
              _controller.animateTo(1.0);
            else // close if none of above
              _controller.animateTo(.0);
          },
          child: new Stack(
            children: <Widget>[
              new SlideTransition(position: animation, child: widget.child),
              new Positioned.fill(
                child: new LayoutBuilder(
                  builder: (context, constraint) {
                    return new AnimatedBuilder(
                      animation: _controller,
                      builder: (context, child) {
                        return new Stack(
                          children: <Widget>[
                            new Positioned(
                              right: .0,
                              top: .0,
                              bottom: .0,
                              width: constraint.maxWidth * animation.value.dx * -1,
                              child: new Container(
                                color: Colors.black26,
                                child: new Row(
                                  children: widget.menuItems.map((child) {
                                    return new Expanded(
                                      child: child,
                                    );
                                  }).toList(),
                                ),
                              ),
                            ),
                          ],
                        );
                      },
                    );
                  },
                ),
              )
            ],
          ),
        );
      }
    }
    

    EDIT

    Flutter no longer allows type Animation<FractionalOffset> in SlideTransition animation property. According to this post https://groups.google.com/forum/#!topic/flutter-dev/fmr-C9xK5t4 it should be replaced with AlignmentTween but this also doesn't work. Instead, according to this issue: https://github.com/flutter/flutter/issues/13812 replacing it instead with a raw Tween and directly creating Offset object works instead. Unfortunately, the code is much less clear.

    0 讨论(0)
提交回复
热议问题