Flutter - 如何使用 FlipCard 将之前的卡片翻转回来

Flutter - How to flip the previous card back using FlipCard

经过几天的搜索,我得到了帮助。 我在开发一个 flutter 应用程序。

上下文:

A grid view feeded with Json

-childs : GridTile with Flipcard in (https://pub.dev/packages/flip_card)

-On tap on GridTile there is a callback to get the selected Item and an animation because of the flipcard onTap

我会:

  1. When an item is aleready selected (flipcard flipped so we show the back of the card),
  2. And I selected another item of the grid te(so flipcard of this itme also flipped)
  3. I would like to flip back the old selected item Flipcard without rebuild the tree because I would lost the state of the new selected item.

我尝试了很多东西。例如,我尝试在 GridTiles 上使用 GlobalKey 在构建后进行交互,但是当我想与之交互时,currentState 始终为 null。

我想知道在这种情况下有什么好的做法?

我希望我没说错 :)(我是法国人)

感谢社区!

.

要知道的事...

可以像这样与 flipcard(child of gridtile)互动

(GlobalKey)

GlobalKey<FlipCardState> cardKey = GlobalKey<FlipCardState>();

@override
Widget build(BuildContext context) {
  return FlipCard(
    key: cardKey,
    flipOnTouch: false,
    front: Container(
      child: RaisedButton(
        onPressed: () => cardKey.currentState.toggleCard(),
        child: Text('Toggle'),
      ),
    ),
    back: Container(
      child: Text('Back'),
    ),
  );
}

我不确定我是否理解您的问题,但这里有一个示例,说明如何将 GridViewFlipCards:

一起使用
var cardKeys = Map<int, GlobalKey<FlipCardState>>();
GlobalKey<FlipCardState> lastFlipped;

Widget _buildFlipCard(String text, Color color, int index) {
  return SizedBox(
    height: 120.0,
    child: Card(
      color: color,
      child: Center(
        child:
            Text(text, style: TextStyle(color: Colors.white, fontSize: 20.0)),
      ),
    ),
  );
}

@override
Widget build(BuildContext context) {
  return Scaffold(
    appBar: AppBar(title: Text("FlipCards")),
    body: GridView.builder(
      itemCount: 20,
      itemBuilder: (context, index) {
        cardKeys.putIfAbsent(index, () => GlobalKey<FlipCardState>());
        GlobalKey<FlipCardState> thisCard = cardKeys[index];
        return Column(
          mainAxisSize: MainAxisSize.min,
          children: <Widget>[
            FlipCardWithKeepAlive(
              child: FlipCard(
                flipOnTouch: false,
                key: thisCard,
                front: _buildFlipCard("$index", Colors.blue, index),
                back: _buildFlipCard("$index", Colors.green, index),
                onFlip: () {
                  if (lastFlipped != thisCard) {
                    lastFlipped?.currentState?.toggleCard();
                    lastFlipped = thisCard;
                  }
                },
              ),
            ),
            RaisedButton(
              child: Text("Flip Card"),
              onPressed: () => cardKeys[index].currentState.toggleCard(),
            )
          ],
        );
      },
      gridDelegate:
          SliverGridDelegateWithFixedCrossAxisCount(crossAxisCount: 2),
    ),
  );
}

class FlipCardWithKeepAlive extends StatefulWidget {
  final FlipCard child;

  FlipCardWithKeepAlive({Key key, this.child}) : super(key: key);

  @override
  State<StatefulWidget> createState() => FlipCardWithKeepAliveState();
}

class FlipCardWithKeepAliveState extends State<FlipCardWithKeepAlive>
    with AutomaticKeepAliveClientMixin {
  @override
  Widget build(BuildContext context) {
    super.build(context);
    return widget.child;
  }

  @override
  bool get wantKeepAlive => true;
}

您需要为列表的每个元素使用不同的键,在本例中我使用了 Map

我还用自定义 FlipCardWithKeepAlive 有状态小部件包装了 FlipCard,该小部件使用 AutomaticKeepAliveClientMixin 在滚动时使 FlipCard 保持活动状态。


编辑: 我更新了代码,因此当您翻转一张卡片时,之前翻转的卡片会翻转回来。基本上你需要保存最后一张翻转的卡片,当一张新的翻转时,翻转最后一张并将新的一张作为最后翻转。

代码会让两张牌同时翻转,如果你想让一张牌等待另一张牌使用onFlipDone()而不是onFlip(),像这样:

onFlipDone: (isFront) {
  bool isFlipped = !isFront;
  if (isFlipped && lastFlipped != thisCard) {
    lastFlipped?.currentState?.toggleCard();
    lastFlipped = thisCard;
  }
}