flutter - 如何在 flutter 中创建类似 Tinder 的堆叠卡片?

标签 flutter dart flutter-layout tinder swipecardview

我想在 flutter 中创建可滑动的类似 tinder 的卡片,它可以在向左或向右滑动时调用某些功能,但在 Flutter 中这样做似乎太复杂了。现在我已经使用带有 Dismissible 的 ListView 生成器实现了该功能,它按预期工作,我可以在用户滑动时通过 API 调用更新列表,但 UI 看起来不那么吸引人,因为卡片在水平关闭时不会旋转.在发帖之前我已经阅读了很多博客文章,虽然其中一些给出了实现此目的的想法,但不可能使用这些技术在后台更新列表,例如使用堆栈创建一副纸牌,如本例所示。 https://github.com/geekruchika/FlutterCardSwipe

这是我当前与滑动相关的代码。

import 'package:flutter/material.dart';
import 'package:provider/provider.dart';


import 'loader.dart';
import '../screens/profile_overview.dart';
import '../providers/user.dart';

class SwipeProfiles extends StatefulWidget {
  final double deviceHeight;
  final double deviceWidth;
  SwipeProfiles(this.deviceHeight, this.deviceWidth);
  @override
  _SwipeProfilesState createState() => _SwipeProfilesState();
}

class _SwipeProfilesState extends State<SwipeProfiles> {
  List _profiles = [];
  bool _isLoading = true;
  bool _gettingMoreProducts = false;

  _loadMoreProfiles() async {
    print('Reached end of list');
    if (_gettingMoreProducts) {
      print('Already getting products');
      return;
    }
    print('Firestore function called');
    _gettingMoreProducts = true;
    dynamic newProfiles =
        await Provider.of<User>(context, listen: false).getProfiles();
    _profiles.addAll(newProfiles);
    setState(() {});
    print('New Products added');
    _gettingMoreProducts = false;
  }

  @override
  void initState() {
    print('Getting new products from init state');
    Provider.of<User>(context, listen: false).getProfiles().then((profiles) {
      setState(() {
        _profiles = profiles;
        _isLoading = false;
      });
    });
    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    return Container(
        margin: EdgeInsets.all(10),
        height: widget.deviceHeight * 0.75,
        decoration: BoxDecoration(borderRadius: BorderRadius.circular(10)),
        child: _isLoading
            ? Loader()
            : ListView.builder(
                itemCount: _profiles.length,
                itemBuilder: (context, index) {
                  if (index == _profiles.length - 1) {
                    _loadMoreProfiles();
                  }
                  return Dismissible(
                    key: UniqueKey(),
                    onDismissed: (direction) {
                      setState(() {
                        _profiles.removeAt(index);
                      });
                    },
                    background: Container(
                      color: Colors.red,
                      child: Icon(
                        Icons.cancel,
                        color: Colors.white,
                        size: 50,
                      ),
                    ),
                    secondaryBackground: Container(
                      color: Colors.green,
                      child: Icon(
                        Icons.check,
                        color: Colors.white,
                        size: 50,
                      ),
                    ),
                    child: Padding(
                      padding: const EdgeInsets.all(8.0),
                      child: ProfileOverview(_profiles[index],
                          widget.deviceHeight, widget.deviceWidth),
                    ),
                  );
                },
              ));
  }
}

最佳答案

可以直接使用包https://pub.dev/packages/flutter_tindercard
或引用源码
在输出中,您可以看到列表长度没有改变,您可以检测到向左或向右滑动

swipeCompleteCallback:
                (CardSwipeOrientation orientation, int index) {
              print(orientation.toString());
              if (orientation == CardSwipeOrientation.LEFT) {
                print("Card is LEFT swiping");
                print(welcomeImages.length);
              } else if (orientation == CardSwipeOrientation.RIGHT) {
                print("Card is RIGHT swiping");
                print(welcomeImages.length);
              }
            },

工作演示

enter image description here

输出

I/flutter (32086): CardSwipeOrientation.LEFT
I/flutter (32086): Card is LEFT swiping
I/flutter (32086): 3
I/flutter (32086): CardSwipeOrientation.RIGHT
I/flutter (32086): Card is RIGHT swiping
I/flutter (32086): 3

完整代码

import 'package:flutter/material.dart';
import 'package:flutter_tindercard/flutter_tindercard.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,
      ),
      home: ExampleHomePage(),
    );
  }
}

class ExampleHomePage extends StatefulWidget {
  @override
  _ExampleHomePageState createState() => _ExampleHomePageState();
}

class _ExampleHomePageState extends State<ExampleHomePage>
    with TickerProviderStateMixin {
  List<String> welcomeImages = [
    "assets/welcome0.png",
    "assets/welcome1.png",
    "assets/welcome2.png",
  ];

  @override
  Widget build(BuildContext context) {
    CardController controller; //Use this to trigger swap.

    return new Scaffold(
      body: new Center(
        child: Container(
          height: MediaQuery.of(context).size.height * 0.6,
          child: new TinderSwapCard(
            orientation: AmassOrientation.BOTTOM,
            totalNum: welcomeImages.length,
            stackNum: 3,
            swipeEdge: 4.0,
            maxWidth: MediaQuery.of(context).size.width * 0.9,
            maxHeight: MediaQuery.of(context).size.width * 0.9,
            minWidth: MediaQuery.of(context).size.width * 0.8,
            minHeight: MediaQuery.of(context).size.width * 0.8,
            cardBuilder: (context, index) {
              print('index ${index}');
              return Card(
                child: Image.asset('${welcomeImages[index]}'),
              );
            },
            cardController: controller = CardController(),
            swipeUpdateCallback: (DragUpdateDetails details, Alignment align) {
              /// Get swiping card's alignment
              if (align.x < 0) {
                //print("Card is LEFT swiping");
              } else if (align.x > 0) {
                //print("Card is RIGHT swiping");
              }
            },
            swipeCompleteCallback:
                (CardSwipeOrientation orientation, int index) {
              print(orientation.toString());
              if (orientation == CardSwipeOrientation.LEFT) {
                print("Card is LEFT swiping");
                print(welcomeImages.length);
              } else if (orientation == CardSwipeOrientation.RIGHT) {
                print("Card is RIGHT swiping");
                print(welcomeImages.length);
              }
            },
          ),
        ),
      ),
    );
  }
}

关于flutter - 如何在 flutter 中创建类似 Tinder 的堆叠卡片?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61104843/

相关文章:

dart - Flutter 从 Firebase 存储中获取下载地址

android - 如何将 Flutter Date 转换为 TimeStamp?

dart - 将多张 map 组合/合并为一张 map

dart - 自定义 AppBar Flutter

flutter - 屏幕底部的SliverAppBar( flutter )

Flutter for web,无法输入 TextField

Flutter 圆形头像带边框

flutter - Rxdart Vanilla Bloc中的Flutter Debounce API调用

flutter - 如何设置这种文本字段的样式

json - 无法在 flutter dart 中使用 REST API 发送截获的短信