简体   繁体   中英

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. 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. 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. 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.

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

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. 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. changes to 5, which was the state of the previous card.

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. 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. My fear is that it is a problem inside the imported tinder swap card package, but maybe you have some ideas.

I'm new to stack overflow and flutter, so I hope you understand my question and can help me, thanks!

Since ExampleWidget is a stateful widget, you are going have to assign a key to each one of them. For more details, read this article: https://medium.com/flutter/keys-what-are-they-good-for-13cb51742e7d

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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