简体   繁体   English

Flutter 火种交换卡奇怪的更新行为

[英]Flutter tinder swap card weird update behaviour

I try to build a tinder-like swiping feature, where every card is capable of showing several pictures.我尝试构建一个类似 tinder 的滑动功能,每张卡片都可以显示多张图片。 These images are inside a stateful widget.这些图像位于有状态的小部件内。 If I tap on the picture, the next picture is shown.如果我点击图片,则会显示下一张图片。 In initState() I call number = 0 so that every time, I swipe and the next card appears, the first picture is shown.在 initState() 中,我调用 number = 0 ,这样每次我刷卡并出现下一张卡片,就会显示第一张图片。 However, if I tap on the screen to see the second picture of the current card, and I swipe to see the next card, there is a weird behaviour.但是,如果我点击屏幕查看当前卡片的第二张图片,然后滑动查看下一张卡片,就会出现奇怪的行为。 Instead of showing the first picture (which I try to guarantee by calling number = 0 in initState()), the state of the previous card is saved and the second picture appears automatically.不是显示第一张图片(我尝试通过在 initState() 中调用 number = 0 来保证),而是保存前一张卡的 state 并自动显示第二张图片。 My expectation was that every single tinder card is a separate stateful widget that is initialized by number = 0. It seems that this is not the case.我的期望是每张 tinder 卡都是一个单独的有状态小部件,由 number = 0 初始化。似乎情况并非如此。

Below a minimal code example to show what I mean:下面是一个最小的代码示例来说明我的意思:

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

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

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

class MyHomePage extends StatefulWidget {

  MyHomePage();

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

class _MyHomePageState extends State<MyHomePage> {

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: TinderSwapCard(
        swipeEdge: 6,
        orientation: AmassOrientation.TOP,
        swipeCompleteCallback: handleSwipeCompleted,
        totalNum: 100,
        stackNum: 5,
        maxWidth: MediaQuery.of(context).size.width*0.95,
        maxHeight: MediaQuery.of(context).size.height*0.67,
        minWidth: MediaQuery.of(context).size.width*0.949,
        minHeight: MediaQuery.of(context).size.height*0.669,
        cardBuilder: (context, index) => buildCard(index),
      ),
    );
  }

  void handleSwipeCompleted(CardSwipeOrientation orientation, int index) {
    switch (orientation) {
      case CardSwipeOrientation.LEFT:
        break;
      case CardSwipeOrientation.RIGHT:
        break;
      case CardSwipeOrientation.RECOVER:
        break;
      default:
        break;
    }
  }

  Widget buildCard(int index) {
    return Center(
      child: Container(
        padding: EdgeInsets.only(top: 100),
        color: Colors.grey,
        height: MediaQuery.of(context).size.height*0.5,
        child: Column(
          children: <Widget>[
            Text(index.toString()),
            ExampleWidget(),
          ],
        ),
      ),
    );
  }

}

class ExampleWidget extends StatefulWidget {
  @override State<ExampleWidget> createState() => ExampleWidgetState();
}

class ExampleWidgetState extends State<ExampleWidget> {

  int number;

  @override void initState() {
    number = 0;
    super.initState();
  }

  @override Widget build(BuildContext context) {
    return Center(
      child: GestureDetector(
        onTap: () {setState(() {number++;});},
        child: Text(number.toString(), style: TextStyle(color: Colors.red)),
      ),
    );
  }

}

Card No. 4, Picture No. 5 Card No. 5, Picture No. 5 4 号卡,5号图片 5 号卡,5 号图片

In this code example, you can see a grey tinder card with two numbers: The first number (black) stands for the current card and the second number (red) stands for the current picture number.在此代码示例中,您可以看到带有两个数字的灰色火种卡:第一个数字(黑色)代表当前卡片,第二个数字(红色)代表当前图片编号。 If you tap on the red number, the next picture is shown (number is increased).如果您点击红色数字,则会显示下一张图片(数字增加)。

In the first screenshot you can see card no.在第一个屏幕截图中,您可以看到卡号。 4 with picture no. 4 有图片编号。 5. If I swipe, so the next card appears, the first state is correct (card no. 5 and picture no. 0), but few milliseconds later the picture no. 5.如果我刷卡,那么出现下一张卡片,第一个state是正确的(卡号5和图片号0),但几毫秒后图片号。 changes to 5, which was the state of the previous card.更改为 5,即前一张卡的 state。

What is the problem here?这里有什么问题? I found a workaround by including the didUpdateWidget(Widget oldWidget) method inside the stateful widget, which sets the number to 0 for the next picture, but it is not a good solution because it is triggered as soon as I swipe the card.我通过在有状态小部件中包含 didUpdateWidget(Widget oldWidget) 方法找到了一种解决方法,该方法将下一张图片的数字设置为 0,但这不是一个好的解决方案,因为我一刷卡就会触发它。 So if the second picture is shown and I swipe, it immediately jumps to the first picture.因此,如果显示第二张图片并且我滑动,它会立即跳转到第一张图片。 Thats solves the problem of the next card but looks bad on the current card.这解决了下一张卡的问题,但在当前卡上看起来很糟糕。 Another attempt was to call number = 0 on the dispose() or deactivate() method, but it did not work.另一种尝试是在 dispose() 或 deactivate() 方法上调用 number = 0,但它不起作用。 My fear is that it is a problem inside the imported tinder swap card package, but maybe you have some ideas.我担心是进口的火种交换卡package内部有问题,但也许你有一些想法。

I'm new to stack overflow and flutter, so I hope you understand my question and can help me, thanks!我是堆栈溢出和 flutter 的新手,所以希望您能理解我的问题并能帮助我,谢谢!

Since ExampleWidget is a stateful widget, you are going have to assign a key to each one of them.由于ExampleWidget是一个有状态的小部件,因此您必须为每个小部件分配一个键。 For more details, read this article: https://medium.com/flutter/keys-what-are-they-good-for-13cb51742e7d有关更多详细信息,请阅读本文: https://medium.com/flutter/keys-what-are-they-good-for-13cb51742e7d

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM