选择一张卡片是在水平列表中选择其他卡片

Posted

技术标签:

【中文标题】选择一张卡片是在水平列表中选择其他卡片【英文标题】:Selecting a card is selecting other cards in horizontal list 【发布时间】:2019-08-24 22:01:59 【问题描述】:

我正在为应用程序使用simple coverflow 插件。每个容器都可以水平滚动,并且有一个标题,有 3 个选项:Card

问题是当我选择任何卡片选项时,它也会在列表中的其他卡片上选择相同的选项,如下所示:

正如您在上面看到的,当我从第一个容器中选择卡#1 时,最左侧和最右侧的卡以绿色显示所选卡选项。

我需要做什么才能从中心卡中选择一个选项,该选项不会突出显示/在其他卡上选择相同的选项?

代码如下:

  @override
  Widget build(BuildContext context) 
    return new Scaffold(
            body: new CoverFlow(
              dismissedCallback: disposeDismissed,
              currentItemChangedCallback: (int index) 
                print(index);
              ,
              height: 600,
              itemCount: d.length,
              itemBuilder: (BuildContext context, int index) 
                return Container(
                  child: Card(
                    shape: RoundedRectangleBorder(
                        borderRadius: BorderRadius.circular(30)),
                    child: Column(children: <Widget>[
                      Padding(
                        padding: EdgeInsets.symmetric(vertical: 25.0),
                        child: Text(
                          "Test",
                          style: TextStyle(
                              fontSize: 20.0, fontWeight: FontWeight.bold),
                        ),),
                      Container(
                          height: 50.0,
                          child: GestureDetector(
                            child: Card(
                                color: _c
                                    ? Colors.lightGreen
                                    : Colors.white,
                                shape: RoundedRectangleBorder(
                                    borderRadius: BorderRadius.circular(20.0)),
                                margin: EdgeInsets.symmetric(
                                    horizontal: 10, vertical: 6),
                                child: Center(
                                    child: Text("1",
                                        style: TextStyle(
                                            fontSize: 18.0),
                                        textAlign: TextAlign.center))
                            ),
                            onTap: () 
                              setState(() 
                                _s = true;
                                _c = true;
                                _w = false;
                                _wr = false;
                              );
                            ,)),
                      Container(
                          height: 50.0,
                          child: GestureDetector(
                            child: Card(
                                color:
                                    _w ? Colors.redAccent : Colors.white,
                                shape: RoundedRectangleBorder(
                                    borderRadius: BorderRadius.circular(20.0)),
                                margin: EdgeInsets.symmetric(
                                    horizontal: 10, vertical: 6),
                                child: Center(
                                    child: Text(
                                  "2",
                                  style: TextStyle(
                                      fontSize: 18.0),
                                  textAlign: TextAlign.center,
                                ))),
                            onTap: () 
                              setState(() 
                                _s = false;
                                _c = false;
                                _w = true;
                                _wr = false;
                              );
                            ,
                          )),
                      Container(
                          height: 50.0,
                          child: GestureDetector(
                            child: Card(
                                color: _wr
                                    ? Colors.redAccent
                                    : Colors.white,
                                shape: RoundedRectangleBorder(
                                    borderRadius: BorderRadius.circular(20.0)),
                                margin: EdgeInsets.symmetric(
                                    horizontal: 10, vertical: 6),
                                child: Center(
                                  child: Text(
                                    "3",
                                    textAlign: TextAlign.center,
                                    style: TextStyle(
                                        fontSize: 18.0),
                                  ),)),
                            onTap: () 
                              setState(() 
                                _s = false;
                                _c = false;
                                _w = false;
                                _wr = true;
                              );
                            ,
                          )),
                      Padding(
                        padding: EdgeInsets.only(top: 25.0),
                      )
                    ]
                    ),
                  ),
                );
              ,
            ));

  Widget widgetBuilder(int i) 
    if (d.length == 0) 
      return Container();
     else 
      print([i % d.length]);
      return d[i % d.length];
    
  disposeDismissed(int dismissedItem, DismissDirection direction) 
    d.removeAt(dismissedItem % d.length);
  

【问题讨论】:

【参考方案1】:

我认为您对 3 张卡片使用相同的状态,因此您的所有 3 张卡片的 _c 变量都是相同的。

您可以创建一个新的StatefulWidget 来构建一张卡片(并在其中拥有自己的_c var),或者您可以使用由index 索引的数组(ListMapCoverFlow 在您的实际小部件中。

选项 1:

class CustomCard extends StatefulWidget 
  @override
  _CustomCardState createState() => _CustomCardState();


class _CustomCardState extends State<CustomCard> 
  // Initialise here or in `initState()` method.
  bool _s = false;
  bool _c = false;
  bool _w = false;
  bool _wr = false;

  @override
  Widget build(BuildContext context) 
    return Card(
        shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(30)),
        child: Column(children: <Widget>[
          Padding(
            padding: EdgeInsets.symmetric(vertical: 25.0),
            child: Text(
              "Test",
              style: TextStyle(fontSize: 20.0, fontWeight: FontWeight.bold),
            ),
          ),
          Container(
              height: 50.0,
              child: GestureDetector(
                child: Card(
                    color: _c ? Colors.lightGreen : Colors.white,
                    shape: RoundedRectangleBorder(
                        borderRadius: BorderRadius.circular(20.0)),
                    margin: EdgeInsets.symmetric(horizontal: 10, vertical: 6),
                    child: Center(
                        child: Text("1",
                            style: TextStyle(fontSize: 18.0),
                            textAlign: TextAlign.center))),
                onTap: () 
                  setState(() 
                    _s = true;
                    _c = true;
                    _w = false;
                    _wr = false;
                  );
                ,
              )),
          Container(
              height: 50.0,
              child: GestureDetector(
                child: Card(
                    color: _w ? Colors.redAccent : Colors.white,
                    shape: RoundedRectangleBorder(
                        borderRadius: BorderRadius.circular(20.0)),
                    margin: EdgeInsets.symmetric(horizontal: 10, vertical: 6),
                    child: Center(
                        child: Text(
                      "2",
                      style: TextStyle(fontSize: 18.0),
                      textAlign: TextAlign.center,
                    ))),
                onTap: () 
                  setState(() 
                    _s = false;
                    _c = false;
                    _w = true;
                    _wr = false;
                  );
                ,
              )),
          Container(
              height: 50.0,
              child: GestureDetector(
                child: Card(
                    color: _wr ? Colors.redAccent : Colors.white,
                    shape: RoundedRectangleBorder(
                        borderRadius: BorderRadius.circular(20.0)),
                    margin: EdgeInsets.symmetric(horizontal: 10, vertical: 6),
                    child: Center(
                      child: Text(
                        "3",
                        textAlign: TextAlign.center,
                        style: TextStyle(fontSize: 18.0),
                      ),
                    )),
                onTap: () 
                  setState(() 
                    _s = false;
                    _c = false;
                    _w = false;
                    _wr = true;
                  );
                ,
              )),
          Padding(
            padding: EdgeInsets.only(top: 25.0),
          )
        ]));
  

  @override
  Widget build(BuildContext context) 
    return new Scaffold(
      body: new CoverFlow(
        dismissedCallback: disposeDismissed,
        currentItemChangedCallback: (int index) 
          print(index);
        ,
        height: 600,
        itemCount: d.length,
        itemBuilder: (BuildContext context, int index) 
          return Container(
            child: CustomCard()
          );
        ,
      ));

  Widget widgetBuilder(int i) 
    if (d.length == 0) 
      return Container();
     else 
      print([i % d.length]);
      return d[i % d.length];
    
  disposeDismissed(int dismissedItem, DismissDirection direction) 
    d.removeAt(dismissedItem % d.length);
  

您可以在 CustomCard 小部件中添加选项。

选项 2:

为您的数据创建一个类:

class MyData 
  bool s = false;
  bool c = false;
  bool w = false;
  bool wr = false;

创建一个列表来存储您的数据(在您的州):

  List<MyData> _cardsData;

  @override
  initState() 
    super.initState();
    _cardsData = List.generate(d.length, (index) => MyData());
  

使用列表:

// ...
onTap: () 
  setState(() 
    _cardsData[index].c = true;
  )

// ...

【讨论】:

这听起来很有希望。你能告诉我你建议的两个选项的代码示例吗? 感谢您的回答。这很有帮助。【参考方案2】:

你只需要指定索引和currentIndex,这段代码就可以了:

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

void main() => runApp(MaterialApp(
      home: MyApp(),
    ));

class MyApp extends StatefulWidget 
  @override
  _MyAppState createState() => _MyAppState();


class _MyAppState extends State<MyApp> 
  int curerntIndex = 0;
  @override
  Widget build(BuildContext context) 
    return new Scaffold(
        body: new CoverFlow(
      dismissedCallback: disposeDismissed,
      currentItemChangedCallback: (int index) 
        print(index);
        setState(() 
          curerntIndex = index;
        );
      ,
      height: 600,
      itemCount: d.length,
      itemBuilder: (BuildContext context, int index) 
        return Item(index, curerntIndex);
      ,
    ));
  


class Item extends StatefulWidget 
  final int index;
  final int curerntIndex;
  Item(this.index, this.curerntIndex);

  @override
  _ItemState createState() => _ItemState(index, curerntIndex);


class _ItemState extends State<Item> 
  final int index;
  final int curerntIndex;

  bool _s = true;
  bool _c = true;
  bool _w = false;
  bool _wr = false;

  _ItemState(this.index, this.curerntIndex);

  @override
  Widget build(BuildContext context) 
    return Container(
      child: Card(
        shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(30)),
        child: Column(children: <Widget>[
          Padding(
            padding: EdgeInsets.symmetric(vertical: 25.0),
            child: Text(
              "Test",
              style: TextStyle(fontSize: 20.0, fontWeight: FontWeight.bold),
            ),
          ),
          Container(
              height: 50.0,
              child: GestureDetector(
                child: Card(
                    color: _c ? Colors.lightGreen : Colors.white,
                    shape: RoundedRectangleBorder(
                        borderRadius: BorderRadius.circular(20.0)),
                    margin: EdgeInsets.symmetric(horizontal: 10, vertical: 6),
                    child: Center(
                        child: Text("1",
                            style: TextStyle(fontSize: 18.0),
                            textAlign: TextAlign.center))),
                onTap: () 
                  if (index == curerntIndex) 
                    setState(() 
                      _s = true;
                      _c = true;
                      _w = false;
                      _wr = false;
                    );
                  
                ,
              )),
          Container(
              height: 50.0,
              child: GestureDetector(
                child: Card(
                    color: _w ? Colors.redAccent : Colors.white,
                    shape: RoundedRectangleBorder(
                        borderRadius: BorderRadius.circular(20.0)),
                    margin: EdgeInsets.symmetric(horizontal: 10, vertical: 6),
                    child: Center(
                        child: Text(
                      "2",
                      style: TextStyle(fontSize: 18.0),
                      textAlign: TextAlign.center,
                    ))),
                onTap: () 
                  if (index == curerntIndex) 
                    setState(() 
                      _s = false;
                      _c = false;
                      _w = true;
                      _wr = false;
                    );
                  
                ,
              )),
          Container(
              height: 50.0,
              child: GestureDetector(
                child: Card(
                    color: _wr ? Colors.redAccent : Colors.white,
                    shape: RoundedRectangleBorder(
                        borderRadius: BorderRadius.circular(20.0)),
                    margin: EdgeInsets.symmetric(horizontal: 10, vertical: 6),
                    child: Center(
                      child: Text(
                        "3",
                        textAlign: TextAlign.center,
                        style: TextStyle(fontSize: 18.0),
                      ),
                    )),
                onTap: () 
                  if (index == curerntIndex) 
                    setState(() 
                      _s = false;
                      _c = false;
                      _w = false;
                      _wr = true;
                    );
                  
                ,
              )),
          Padding(
            padding: EdgeInsets.only(top: 25.0),
          )
        ]),
      ),
    );
  

【讨论】:

这种方法的一个问题是,如果我在向左或向右移动时离开容器,选择会重置。我想保持选择不变。知道如何坚持选择吗? 所以,在这种情况下,你开始得到一个大状态,setState 是不够的,这意味着你需要使用状态管理库:flutter.dev/docs/development/data-and-backend/state-mgmt/…【参考方案3】:

不,不是您是使用 _c 将颜色更改为绿色的人,因此它在所有颜色中都发生了变化,但实际上您只选择了一个。在颤动中,您不必键入 new 来创建新的手势检测器因此,如果您只想更改被点击单元格的颜色,请通过从 currentItemChangedCallback: (int index) 获得的索引来执行此操作,或者仅更改被点击的小部件颜色。

【讨论】:

你能告诉我如何利用currentItemChangedCallback点击单元格吗? 再一次,您只点击了一个,并且事件仅针对一个触发。 所以水龙头实际上可以工作,它只是颜色告诉我您的业务如何为您提供有关如何更改每张卡片颜色的最佳答案希望您明白我在说什么 我不想改变颜色。如果我选择#2、#3,我会这样做。我只想突出显示选定的单元格,而不应该突出显示其他容器中的单元格。 好的,你应该怎么做,currentItemChangedCallback 给你发送当前coverflow的索引对吧?只需为列表中的每一行创建一个数组,就像这里有 3 个 coveflow 创建一个长度为 3 的数组并在其中添加布尔值,并根据从 currentItemChangedCallback 获得的索引,更改数组中的值,如 arrayOfColors[index]=绿色; ps:如果需要,您可以将布尔值放入数组中

以上是关于选择一张卡片是在水平列表中选择其他卡片的主要内容,如果未能解决你的问题,请参考以下文章

在 Flutter Listview 中选择卡片

根据 alertdialog 选项更改卡片颜色

如何在 Flutter 中选择项目时更改卡片颜色?

如何使选择列表出现在另一个元素上?

Reactjs:使用状态挂钩单击时如何选择一张或多张卡片?

Bootstrap 4:手风琴不会折叠卡片