如何在 Flutter 中创建类似 Tinder 的堆叠卡片? [英] How to create a Tinder-like stacked card in flutter?

查看:15
本文介绍了如何在 Flutter 中创建类似 Tinder 的堆叠卡片?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想在 Flutter 中创建可滑动的类似 tinder 的卡片,它可以在左右滑动时调用一些函数,但在 Flutter 中这样做似乎太复杂了.现在我已经使用带有 Dismissible 的列表视图构建器实现了该功能,该功能按预期工作,我可以在用户滑动时通过 API 调用更新列表,但 UI 看起来并不吸引人,因为卡片在水平关闭时不会旋转.在发布之前,我已经阅读了许多博客文章,虽然其中一些给出了实现这一点的想法,但是不可能在后台使用这些技术更新列表,例如使用堆栈来创建一副牌,如本例所示.

输出

I/flutter (32086): CardSwipeOrientation.LEFTI/flutter (32086):卡片向左滑动我/颤振(32086):3I/flutter (32086): CardSwipeOrientation.RIGHTI/flutter (32086): 刷卡正确我/颤振(32086):3

完整代码

import 'package:flutter/material.dart';导入'包:flutter_tindercard/flutter_tindercard.dart';无效的主要()=>运行应用程序(我的应用程序());MyApp 类扩展 StatelessWidget {//这个小部件是您的应用程序的根.@覆盖小部件构建(BuildContext 上下文){返回材料应用程序(标题:颤振演示",主题:主题数据(primarySwatch:颜色.蓝色,),主页:ExampleHomePage(),);}}类 ExampleHomePage 扩展 StatefulWidget {@覆盖_ExampleHomePageState createState() =>_ExampleHomePageState();}类_ExampleHomePageState 扩展状态<ExampleHomePage>与 TickerProviderStateMixin {列表<字符串>欢迎图片 = [资产/welcome0.png","assets/welcome1.png",资产/welcome2.png",];@覆盖小部件构建(BuildContext 上下文){CardController 控制器;//使用它来触发交换.返回新的脚手架(身体:新中心(孩子:容器(高度:MediaQuery.of(context).size.height * 0.6,孩子:新的 TinderSwapCard(方向:AmassOrientation.BOTTOM,总数:welcomeImages.length,堆栈数:3,滑动边缘: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:(上下文,索引){print('index ${index}');退货卡(孩子:Image.asset('${welcomeImages[index]}'),);},卡控制器:控制器 = CardController(),swipeUpdateCallback: (DragUpdateDetails details, Alignment align) {///获取刷卡的对齐方式if (align.x < 0) {//print("卡片向左刷");} else if (align.x > 0) {//print("刷卡正确");}},swipeComplete回调:(CardSwipeOrientation 方向,int 索引){打印(方向.toString());如果(方向== CardSwipeOrientation.LEFT){print("卡片向左刷");打印(welcomeImages.length);} else if (orientation == CardSwipeOrientation.RIGHT) {print("刷卡正确");打印(welcomeImages.length);}},),),),);}}

I want to create swipeable tinder-like cards in flutter which can call some function on left or right swipe but it seems too complicated to do so in Flutter. Right now I have implemented the functionality using list view builder with Dismissible which is working as expected and I can update the list via API call while the user is swiping but UI doesn't look that appealing because the card doesn't rotate while dismissing horizontally. I have read many blog posts before posting here and while some of them give an idea to achieve this but it is not possible to update the list in the background with those techniques like using a stack to create a deck of cards as in this example. https://github.com/geekruchika/FlutterCardSwipe

Here's my current code relevant to swiping.

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),
                    ),
                  );
                },
              ));
  }
}

解决方案

You can directly use package https://pub.dev/packages/flutter_tindercard
or reference source code
In output you can see the List length did not change and you can detect swipe left or right

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);
              }
            },

working demo

output

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

full code

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 中创建类似 Tinder 的堆叠卡片?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆