flutter - 如何在ListView中搜索特定元素?

标签 flutter dart gridview

我有一个listView,它表示为gridView。我添加了一个带有TextController的搜索栏。
网格 View 具有各个元素,这些元素具有名称和年龄。我希望搜索查询搜索名称并仅显示相关元素。

List<Map> itemList = [
{
  'Name':"Bob",
  'Age':"24"
}
{
  'Name':"Billy",
  'Age':"34"
}
]

这是我的GridView的表示形式:
  @override
  Widget build(BuildContext context) {
    return Padding(
      padding: const EdgeInsets.only(top: 8),
      child: FutureBuilder<bool>(
        future: getData(),
        builder: (BuildContext context, AsyncSnapshot<bool> snapshot) {
          if (!snapshot.hasData) {
            return const SizedBox();
          } else {
            return GridView.count( 
              mainAxisSpacing: 32.0,
              crossAxisSpacing: 32.0,
              childAspectRatio: 0.8,
              shrinkWrap: true,
              physics: ClampingScrollPhysics(),
              padding: const EdgeInsets.all(8),
              crossAxisCount: 2,

              children: List<Widget>.generate(
                itemList.length,
                (int index) {
                  return GestureDetector(
                    onTap: () => _goToItemViewer(itemList[index]),
                    child: CategoryView(
                      callback: () {

                      },
                      item: itemList[index],
                    ),
                  );
                },
              ),
            );
          }
        },
      ),
    );
  }
}

class CategoryView extends StatefulWidget {
  final Map item;
  const CategoryView({Key key, this.callback, this.item}) : super(key: key);

  final VoidCallback callback;

  @override
  CategoryViewState createState() => CategoryViewState();
}

class CategoryViewState extends State<CategoryView> {
  @override
  Widget build(BuildContext context) {
    return Container(
      child: InkWell(
        splashColor: Colors.transparent,
        child: SizedBox(
          height: 280,
          child: Stack(
            alignment: AlignmentDirectional.bottomCenter,
            children: <Widget>[
              Container(
                child: Container(
                  child: Column(
                    children: <Widget>[
                      Expanded(
                        child: Container(
                          decoration: BoxDecoration(
                            color: Color(0xfff8fafb),
                            borderRadius:
                                const BorderRadius.all(Radius.circular(16.0)),

                          ),
                          child: Column(
                            children: <Widget>[
                              Expanded(
                                child: Container(
                                  child: Column(
                                    children: <Widget>[
                                      Padding(
                                        padding: const EdgeInsets.only(
                                            top: 16, left: 16, right: 16),
                                        child: Text(
                                          widget.item['Name'],
                                          textAlign: TextAlign.left,
                                          style: TextStyle(
                                            fontWeight: FontWeight.w600,
                                            fontFamily: "Netflix",
                                            fontSize: 16,
                                            letterSpacing: 0.27,
                                            color:
                                                Color(0xFF17262A),
                                          ),
                                        ),
                                      ),
                                      Padding(
                                        padding: const EdgeInsets.only(
                                            top: 8,
                                            left: 16,
                                            right: 16,
                                            bottom: 8),
                                        child: Row(
                                          mainAxisAlignment:
                                              MainAxisAlignment.spaceBetween,
                                          crossAxisAlignment:
                                              CrossAxisAlignment.center,
                                          children: <Widget>[],
                                        ),
                                      ),
                                    ],
                                  ),
                                ),
                              ),
                              const SizedBox(
                                width: 48,
                              ),
                            ],
                          ),
                        ),
                      ),
                      const SizedBox(
                        height: 48,
                      ),
                    ],
                  ),
                ),
              ),
              Container(
                child: Padding(
                  padding: const EdgeInsets.only(top: 24, right: 16, left: 16),
                  child: Container(
                    decoration: BoxDecoration(
                      borderRadius:
                          const BorderRadius.all(Radius.circular(16.0)),
                      boxShadow: <BoxShadow>[
                        BoxShadow(
                            color: Color(0xFF3A5160).withOpacity(0.2),
                            offset: const Offset(0.0, 0.0),
                            blurRadius: 6.0),
                      ],
                    ),
                    child: ClipRRect(
                      borderRadius:
                          const BorderRadius.all(Radius.circular(16.0)),
                      child: AspectRatio(
                        aspectRatio: 1,
                        child: Image(
                          image: NetworkImage(

                            widget.item['Age'],
                          ),
                          fit: BoxFit.fill, // use this
                        ),
                      ),
                    ),
                  ),
                ),
              ),
            ],
          ),
        ),
      ),
    );
  }
}

我的SearchBar分别被调用:
Container(
        child: Column(
          children: <Widget>[
            Padding(
              padding: const EdgeInsets.all(8.0),
              child: TextField(
                onChanged: (value) {

                },
                controller: editingController,
                decoration: InputDecoration(
                    labelText: "Search",
                    hintText: "Search",
                    prefixIcon: Icon(Icons.search),
                    border: OutlineInputBorder(
                        borderRadius: BorderRadius.all(Radius.circular(25.0)))),

              ),
            ),
          ],),),

我需要一种制作重复列表的方法,以搜索给定列表中的元素并仅显示那些元素。

最佳答案

这是一个完整的例子。
像这样做:

import 'package:flutter/material.dart';

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

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

// Main code starts here // Your widget must be stateful
class MyWidget extends StatefulWidget {
  @override
  createState() => _MyWidgetState();
}

// Here is the list of all your people
List<Map> people = [
  {
    'name': 'John',
    'age': 25
  },
  {
    'name': 'Billy',
    'age': 21
  },
  {
    'name': 'Bob',
    'age': 18
  },
  {
    'name': 'Kate',
    'age': 23
  },
  {
    'name': 'Rose',
    'age': 18
  },
  {
    'name': 'David',
    'age': 42
  },
  {
    'name': 'Marc',
    'age': 42
  },
  {
    'name': 'Sophie',
    'age': 38
  },
  {
    'name': 'Bill',
    'age': 77
  },
];

class _MyWidgetState extends State<MyWidget> {
  List<Map> _filtered = people.toList(); // Make a copy of the original list
  TextEditingController _controller = TextEditingController();

  @override
  void dispose() {
    _controller.dispose(); // Remember to dispose the controller
    super.dispose();
  }

  // This method filters the '_filtered' list according to the key
  void filter(String match) {
    setState(() {
      _filtered = people
          .where((data) => data['name'].toLowerCase().contains(match.toLowerCase()))
          .toList();
    }); // Set state to notify flutter that the widget must be rebuilt
  }

  @override
  Widget build(BuildContext context) {
    return Column(
      children: <Widget>[
        Padding(
          padding: const EdgeInsets.all(8.0),
          child: TextField(
            controller: _controller,
            onChanged: filter, // When the text is changed, this method is called, You can do it as lambda too (match) => ....
          ),
        ),
        SizedBox(height: 20),
        Expanded(
          // I have used list view but you can use your own widget like a grid view. The idea is same for both cases
          child: ListView.builder(
            physics: BouncingScrollPhysics(),
            itemCount: _filtered.length, // Filtered list length
            itemBuilder: (context, i) {
              return Padding(
                padding: const EdgeInsets.all(8.0),
                child: Text(_filtered[i]['name'] + ', Age: ' + _filtered[i]['age'].toString(),), // Put your data this way
              );
            },
          ),
        )
      ],
    );
  }
}

结果如下:

No filtering

在您开始输入文字之后:

Filtered

关于flutter - 如何在ListView中搜索特定元素?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60262736/

相关文章:

flutter 停泊 : missing libsqlite3. 所以

flutter - 在文本抖动上绘制水平笔划

dart - 自动将html字符串转换为元素

android - 在对话框中的 gridview 中显示已安装的应用程序列表 - 不工作

c# - asp.net gridview onrowcommand -->( GridViewCommandEventArgs)

flutter - 使用 Dart flutter 向 map 添加条目的最佳方式

asynchronous - 我怎样才能等待一个变量

flutter - 从API中的字符串中删除特殊字符

flutter - 无法在此小部件上方找到正确的提供程序 - Flutter

asp.net - 使用gridview asp.net进行排序和分页