简体   繁体   English

在 Flutter 中选择时更改 ListTile 的背景颜色

[英]Change background color of ListTile upon selection in Flutter

I've made a ListView in Flutter, but now I have some ListTiles in this ListView that can be selected.我在 Flutter 中做了一个ListView ,但是现在这个ListView中有一些ListTiles可以选择。 Upon selection, I want the background color to change to a color of my choice.选择后,我希望背景颜色更改为我选择的颜色。 I don't know how to do that.我不知道该怎么做。 In the docs they mention that a ListTile has a property style .文档中,他们提到ListTile具有属性style However, when I try to add that (as in third last line in the code below), this style property gets a squiggly red line underneath and the compiler tells me that The named parameter 'style' isn't defined .但是,当我尝试添加它时(如下面代码中的倒数第三行),这个style属性在下面有一条弯曲的红线,编译器告诉我The named parameter 'style' isn't defined

Widget _buildRow(String string){
  return new ListTile(
    title: new Text(string),
    onTap: () => setState(() => toggleSelection(string)),
    selected: selectedFriends.contains(string),
    style: new ListTileTheme(selectedColor: Colors.white,),
  );
}

Screenshot:截屏:

在此处输入图像描述


Short answer:简短的回答:

ListTile(
  tileColor: isSelected ? Colors.blue : null, 
)

Full Code:完整代码:

// You can also use `Map` but for the sake of simplicity I'm using two separate `List`.
final List<int> _list = List.generate(20, (i) => i);
final List<bool> _selected = List.generate(20, (i) => false); // Fill it with false initially
  
Widget build(BuildContext context) {
  return Scaffold(
    body: ListView.builder(
      itemBuilder: (_, i) {
        return ListTile(
          tileColor: _selected[i] ? Colors.blue : null, // If current item is selected show blue color
          title: Text('Item ${_list[i]}'),
          onTap: () => setState(() => _selected[i] = !_selected[i]), // Reverse bool value
        );
      },
    ),
  );
}

I was able to change the background color of the ListTile using a BoxDecoration inside Container :我能够使用Container内的BoxDecoration更改 ListTile 的背景颜色:

ListView (
    children: <Widget>[
        new Container (
            decoration: new BoxDecoration (
                color: Colors.red
            ),
            child: new ListTile (
                leading: const Icon(Icons.euro_symbol),
                title: Text('250,00')
            )
        )
    ]
)

If you also need an onTap listener with a ripple effect, you can use Ink :如果你还需要一个带有涟漪效果的onTap监听器,你可以使用Ink

ListView(
  children: [
    Ink(
      color: Colors.lightGreen,
      child: ListTile(
        title: Text('With lightGreen background'),
        onTap() { },
      ),
    ),
  ],
);

连锁反应

It's not ListTile that has the style property.具有style属性的不是ListTile But ListTileTheme .但是ListTileTheme ListTileTheme is an inheritedWidget. ListTileTheme是一个继承的Widget。 And like others, it's used to pass down data (such as theme here).和其他人一样,它用于传递数据(例如这里的主题)。

To use it, you have to wrap any widget above your ListTile with a ListTileTheme containing the desired values.要使用它,您必须使用包含所需值的ListTileTheme将 ListTile上方的任何小部件包装起来。

ListTile will then theme itself depending on the closest ListTileTheme instance.然后ListTile将根据最近的ListTileTheme实例对自身进行主题化。

Wrap ListTile in an Ink .ListTile包裹在Ink中。

Ink(
  color: isSelected ? Colors.blue : Colors.transparent,
  child: ListTile(title: Text('hello')),
)

This is no more pain!这不再是痛苦了!

Now you can use tileColor and selectedTileColor property of ListTile widget to achieve it.现在您可以使用ListTile小部件的tileColorselectedTileColor属性来实现它。

Have a look at this Issue #61347 which got merged into master.看看这个已合并到 master 的问题 #61347

An easy way would be to store the initial index in a variable and then change the state of that variable whenever tapped.一种简单的方法是将初始索引存储在变量中,然后在点击时更改该变量的状态。

   ListView.builder(
              shrinkWrap: true,
              itemCount: 4,
              itemBuilder: (context, index) {
                return Container( //I have used container for this example. [not mandatory]
                    color: tappedIndex == index ? Colors.blue : Colors.grey,
                    child: ListTile(
                        title: Center(
                      child: Text('${index + 1}'),
                    ),onTap:(){
                          setState((){
                            tappedIndex=index;
                          });
                        }));
              })

full code:完整代码:

import 'package:flutter/material.dart';

void main() {
  runApp(MyApp());
}

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

class MyWidget extends StatefulWidget {
  @override
  MyWidgetState createState() => MyWidgetState();
}

class MyWidgetState extends State<MyWidget> {
  late int tappedIndex;

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

  @override
  Widget build(BuildContext context) {
    return Scaffold(
        body: Column(
            mainAxisAlignment: MainAxisAlignment.center,
            crossAxisAlignment: CrossAxisAlignment.center,
            children: [
          ListView.builder(
              shrinkWrap: true,
              itemCount: 4,
              itemBuilder: (context, index) {
                return Container(
                    color: tappedIndex == index ? Colors.blue : Colors.grey,
                    child: ListTile(
                        title: Center(
                      child: Text('${index + 1}'),
                    ),onTap:(){
                          setState((){
                            tappedIndex=index;
                          });
                        }));
              })
        ]));
  }
}

Dartpad link: https://dartpad.dev/250ff453b97cc79225e8a9c657dffc8a飞镖板链接: https ://dartpad.dev/250ff453b97cc79225e8a9c657dffc8a

I know that the original question has been answered, but I wanted to add how to set the color of ListTile while the tile is being pressed .我知道原始问题已得到解答,但我想添加如何在按下瓷砖时设置ListTile的颜色 The property you are looking for is called highlight color and it can be set by wrapping the ListTile in a Theme widget, like this:您要查找的属性称为highlight color ,可以通过将ListTile包装在Theme小部件中来设置它,如下所示:

Theme(
  data: ThemeData(
    highlightColor: Colors.red,
  ),
  child: ListTile(...),
  )
);

Note: if the Theme widget resets the font of text elements inside the ListTile , just set its fontFamily property to the same value You used in other places in your app.注意:如果Theme小部件重置ListTile中文本元素的字体,只需将其fontFamily属性设置为您在应用程序的其他位置使用的相同值。

Unfortunately, ListTile doesn't have background-color property.不幸的是, ListTile 没有 background-color 属性。 Hence, we have to simply wrap the ListTile widget into a Container/Card widget and then we can use its color property.因此,我们必须简单地将 ListTile 小部件包装到 Container/Card 小部件中,然后我们可以使用它的颜色属性。 Further, We have to provide SizedBox widget with some height to separate the same colored ListTiles.此外,我们必须提供具有一定高度的 SizedBox 小部件来分隔相同颜色的 ListTiles。

I am sharing that worked for me :)我正在分享对我有用的东西:)

I hope it will definitely help you.我希望它肯定会帮助你。

Screenshot: see how it works截图:看看它是如何工作的

            return 
              ListView(
                children: snapshot.data.documents.map((doc) {
                  return Column(children: [
                    Card(
                      color: Colors.grey[200],
                       child: ListTile(
                      leading: Icon(Icons.person),
                      title: Text(doc.data['coursename'], style: TextStyle(fontSize: 22),),
                      subtitle: Text('Price: ${doc.data['price']}'),
                      trailing: IconButton(
                        icon: Icon(Icons.delete),
                        onPressed: () async {
                          await Firestore.instance
                              .collection('courselist')
                              .document(doc.documentID)
                              .delete();
                        },
                      ),
                  ),
                    ),
                 SizedBox(height: 2,)
                  ],);
                }).toList(),[enter image description here][1]
              );

I have used as我用过

ListTile(
                title: Text('Receipts'),
                leading: Icon(Icons.point_of_sale),
                tileColor: Colors.blue,
              ),  

There are two props: tileColor and selectedTileColor.有两个道具:tileColor 和 selectedTileColor。

tileColor - when the tile/row is Not selected; tileColor - 当瓷砖/行未被选中时;

selectedTileColor - when the tile/row is selected selectedTileColor - 当瓷砖/行被选中时

ListTile(
        selected: _isSelected,
        tileColor: Colors.blue,
        selectedTileColor: Colors.greenAccent,
)

I was able to change the Background Color of ListTile by making it a child of Container Widget and adding color to the Container Widget.我可以通过将 ListTile 设为 Container Widget 的子级并向 Container Widget 添加颜色来更改其背景颜色。

Here drawerItem is the model class which holds the isSelected value.这里的drawerItem 是保存isSelected 值的模型类。 Color of background depends on isSelected value.背景颜色取决于 isSelected 值。

Note: For unselected items keep the color Transparent so you will still get the ripple effect.注意:对于未选中的项目,请保持颜色透明,这样您仍然可以获得涟漪效果。

 for (var i = 0; i < drawerItems.length; i++) {
      var drawerItem = drawerItems[i];
      drawerOptions.add(new Container(
        color: drawerItem.isSelected
            ? Colors.orangeAccent
            : Colors.transparent,
        child: new ListTile(
          title: new Row(
            mainAxisAlignment: MainAxisAlignment.spaceBetween,
            children: <Widget>[Text(drawerItem.title), drawerItem.count],
          ),
          leading: SvgPicture.asset(
            drawerItem.icon,
            width: 34,
            height: 34,
          ),
          onTap: () {
            _handleNavigation(i);
          },
          selected: drawerItem.isSelected,
        ),
      ));
    }

在此处输入图像描述

Your answer has been answered in Github .您的答案已在Github中得到解答。

Card(
  color: Colors.white,
  shape: ContinuousRectangleBorder(
    borderRadius: BorderRadius.zero,
  ),
  borderOnForeground: true,
  elevation: 0,
  margin: EdgeInsets.fromLTRB(0,0,0,0),
  child: ListTile(
    // ...
  ),
)

enter image description here >Make variable在此处输入图像描述>使变量

        int slectedIndex;

on tap随叫随到

     onTap:(){
                      setState(() {
                      selectedIndex=index;
                     })

Tile property瓷砖属性

            color:selectedIndex==index?Colors.red :Colors.white,

Same As in List View Builder与列表视图生成器相同

        ListView.builder(
                          itemCount: 10,
                          scrollDirection:Axis.vertical,
                          itemBuilder: (context,index)=>GestureDetector(
                            onTap:(){
                              setState(() {
                                selectedIndex=index;
                              });
                              
                            } ,
                            child: Container(
                              margin: EdgeInsets.all(8),
                              decoration: BoxDecoration(
                                borderRadius: BorderRadius.circular(5),
                                color:selectedIndex==index?Colors.red :Colors.white,
                              ),)

Use the Material widget with InkWell Widget then put inside it the ListTile as shown here in this example:将 Material 小部件与 InkWell 小部件一起使用,然后将 ListTile 放入其中,如下例所示:

return Material(
      color: Colors.white,
      child: ListTile(
          hoverColor: Colors.greenAccent,
          onLongPress: longPressCallback,
          title: Text(
            '$taskTitle',
            style: TextStyle(
                decoration: isChecked
                    ? TextDecoration.lineThrough
                    : TextDecoration.none),
          ),
          trailing: Checkbox(
              activeColor: Colors.lightBlueAccent,
              value: isChecked,
              onChanged: checkboxCallback)),
    );

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

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