【问题标题】:ListTile Card color onTapListTile 卡片颜色 onTap
【发布时间】:2023-03-25 03:33:01
【问题描述】:

我正在尝试在卡片小部件中实现通话按钮,

当我按下通话按钮时,我希望整个卡片背景变为蓝色(如选中),并在按下任何其他卡片时恢复正常,例如使通话按钮切换卡片选择, 尝试使用 setState 函数但它不起作用,因为它仅在我点击整张卡片而不是其中的特定按钮时才会改变颜色。 如何在按下通话按钮时选择整张卡并在按下任何其他卡时释放(从拨号器应用程序返回后)

这是我的代码:

_launchCaller() async {
  const url = "tel:+972545522973";
  if (await canLaunch(url)) {
    await launch(url);
  } else {
    throw 'Could not launch $url';
  }
}
return Padding(
  padding: const EdgeInsets.only(top: 8.0),
  child: Card(
    margin: EdgeInsets.fromLTRB(20.0, 6.0, 20.0, 0.0),
    color: Colors.brown[30],
    child: ListTile(
      isThreeLine: true,
      title: Row(
        children: <Widget> [
          Container(
            child:Text(widget.helpRequest.category.description) ,
            alignment: Alignment.topLeft,
          ),
          Spacer(),
          Container(
            child:Text(formatter.format(now)),
            alignment: Alignment.topRight,
          ),
        ]
      )
      ,
      subtitle: Container(
        child: Column(
            crossAxisAlignment: CrossAxisAlignment.start,
          children: <Widget>[
            GetUserName(widget.helpRequest.sender_id, DataBaseService().userInNeedCollection),
            Text(widget.helpRequest.description),
          ]
        )
      ),
      trailing: Row(
        mainAxisSize: MainAxisSize.min,
        children: <Widget>[
          GestureDetector(
            onTap: (){
              _launchCaller();
              ** Here i think I should add the code **
            },
            onLongPress: () => print("Long Press: Call"),
            child: Padding(
                padding: EdgeInsets.all(16.0),
                child: Icon(Icons.call,
                    size: 20.0,
                    color: Colors.green,
                    )
            ),
          ),
        ],
      ),
    ),
  ),
);

我尝试使用的这个 setState 函数在我的情况下效果不佳(我正在更改 onTap 函数的状态):

void initState() {
           super.initState();

            color = Colors.transparent;
  }

【问题讨论】:

    标签: flutter card


    【解决方案1】:

    最终输出:

    您可以设置特定卡片的颜色,但要做到这一点,您需要有一些方法来引用选定的卡片被点击,通过这个引用我们可以决定卡片是否被选中,如果是那么根据我们的喜好更改颜色。

    在以下示例中,我或多或少使用了您在问题中所述的相同卡片小部件模板,然后我使用ListView.builder 渲染五张卡片,每张卡片具有相同的功能。

    每当按下呼叫按钮时,该特定卡片对应的index 就会被分配给状态selectedIndex,由此我们可以将颜色分配给选定的卡片。

    这是完整的例子:

    import 'package:flutter/material.dart';
    
    void main() => runApp(MyApp());
    
    class MyApp extends StatelessWidget {
      @override
      Widget build(BuildContext context) {
        return MaterialApp(
          title: 'Flutter Demo',
          debugShowCheckedModeBanner: false,
          theme: ThemeData(
            primarySwatch: Colors.blue,
          ),
          home: MyHomePage(title: 'Flutter Demo Home Page'),
        );
      }
    }
    
    class MyHomePage extends StatefulWidget {
      MyHomePage({Key key, this.title}) : super(key: key);
    
      final String title;
    
      @override
      _MyHomePageState createState() => _MyHomePageState();
    }
    
    class _MyHomePageState extends State<MyHomePage> {
      int selectedIndex;
    
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          appBar: AppBar(
            title: Text(widget.title),
          ),
          body: Padding(
            padding: const EdgeInsets.only(top: 8.0),
            child: ListView.builder(
              itemCount: 5,
              itemBuilder: (context, index) {
                return Padding(
                  padding: const EdgeInsets.only(top: 8.0),
                  child: Card(
                    margin: EdgeInsets.fromLTRB(20.0, 6.0, 20.0, 0.0),
                    color: index == selectedIndex
                        ? Colors.amberAccent
                        : Colors.brown[30],
                    child: ListTile(
                      isThreeLine: true,
                      title: Row(children: <Widget>[
                        Container(
                          child: Text("Some Text"),
                          alignment: Alignment.topLeft,
                        ),
                        Spacer(),
                        Container(
                          child: Text("Some Text"),
                          alignment: Alignment.topRight,
                        ),
                      ]),
                      subtitle: Container(
                          child: Column(
                              crossAxisAlignment: CrossAxisAlignment.start,
                              children: <Widget>[
                            Text("Some Text"),
                          ])),
                      trailing: Row(
                        mainAxisSize: MainAxisSize.min,
                        children: <Widget>[
                          GestureDetector(
                            onTap: () {
                              setState(() {
                                selectedIndex = index;
                              });
                            },
                            onLongPress: () => print("Long Press: Call"),
                            child: Padding(
                              padding: EdgeInsets.all(16.0),
                              child: Icon(
                                Icons.call,
                                size: 20.0,
                                color: Colors.green,
                              ),
                            ),
                          ),
                        ],
                      ),
                    ),
                  ),
                );
              },
            ),
          ),
        );
      }
    }
    

    【讨论】:

    • 我正在拨打电话按钮打开手机上的拨号器应用程序,之后当我从拨号器应用程序返回时,卡仍然会选择,就像它不会让卡被选中一样,并且如果我选择了另一张卡片,它也会被选中……我错过了什么吗?
    • 我没有在物理设备上测试过,你这边试试。如果有一些不受欢迎的行为,解决起来并不难。
    【解决方案2】:

    跟踪点击的项目并传递列表的索引

    int clickedItemPosition = -1;
      
    bool isChecked(currentPosition) => clickedItemPosition == currentPosition;
    

    然后在你的卡片里

     //..
    Card(
        margin: EdgeInsets.fromLTRB(20.0, 6.0, 20.0, 0.0),
        color: isChecked(index) ? Colors.blue : Colors.transparent,
    //..
    

    在手势检测器中更新clickedItemPosition

    //...
    GestureDetector(
                onTap: () => setState(() => clickedItemPosition = index),
                //..
    

    【讨论】:

      猜你喜欢
      • 2021-03-18
      • 2021-07-21
      • 2021-12-04
      • 1970-01-01
      • 2021-09-21
      • 1970-01-01
      • 2022-01-20
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多