首页 > 解决方案 > 如何使用 json 文件为 listview.Builder 添加搜索栏?

问题描述

在我的应用程序 Flutter 中,我有一个带有这个主体的小部件

body: ListView.builder(
        itemCount: data.length,
        itemBuilder: (BuildContext context, int index) {
          return Column(
            children: <Widget>[
              ListTile(
                title: Text(data[index]['name']),
                leading: Icon(Icons.arrow_forward_ios),
                onTap: () => {
                  Navigator.pushNamed(context, data[index]['routes'])
                  // Your Logout method
                },
                //title: Text(data[index]['name']),
              )
            ],
          );
        },
      ),

可变数据取决于本地 json 文件。json文件是这样的:

[
    {
        "name" : "name",
        "routes" : "/routes1"
    },
    {
        "name" : "name2",
        "routes" :  "/routes2"
    },
]

对于更新 json 文件,我使用此代码

Future<String> loadJsonData() async {
    var jsonText =
        await rootBundle.loadString('assets/file.json');
    setState(() {
      data = json.decode(jsonText);
    });
    print(jsonText);
  }

  @override
  // ignore: must_call_super
  void initState() {
    this.loadJsonData();
  }

使用此代码,我有一个列表,可以让我看到名称并通过“路线”将我发送到另一个页面。

我需要添加一个搜索栏,它允许我在输入名称时只显示相似的名称。例如,如果 json 文件中的列表名称是:Martin Mike James

当我开始输入“M”时,我将看到 Martin Mike 的列表。

有什么建议么?

谢谢

标签: jsonfluttersearchbar

解决方案


由于列表是本地的,不会更改。可以通过使用简单的有状态小部件来实现搜索。

最简单的方法是在状态中为过滤器名称添加一个变量,并根据搜索文本使用过滤器名称设置状态。在这里,我使用了一个字符串项目,请使用适合您需要的类。

allNames变量包含所有名称。

searchedNames变量包含所有名称。

_searchChanged函数 setsState 与 searchedName 基于输入的测试TextField

// Widget for searching through a string list.
class SearchNameWidget extends StatefulWidget {
  SearchNameWidget({Key key}) : super(key: key);

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

class _SearchNameState extends State<SearchNameWidget> {
  // All names
  List<String> allNames = [
    'one',
    'two',
    'three',
    'four',
    'five',
    'six',
    'seven',
    'eight',
    'nine',
    'ten'
  ];

  // searched names
  List<String> searchedNames = [
    'one',
    'two',
    'three',
    'four',
    'five',
    'six',
    'seven',
    'eight',
    'nine',
    'ten'
  ];

  // changes the filtered name based on search text and sets state.
  void _searchChanged(String searchText) {
    if (searchText != null && searchText.isNotEmpty) {
      setState(() {
        searchedNames =
            List.from(allNames.where((name) => name.contains(searchText)));
      });
    }
    else {
      setState(() {
        searchedNames =
            List.from(allNames);
      });
    }
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Demos'),
      ),
      body: Column(
        children: [
          TextField(
            // calls the _searchChanged on textChange
            onChanged: (search) => _searchChanged(search),
          ),
          Expanded(
            child: ListView.builder(
              itemCount: searchedNames.length,
              itemBuilder: (context, index) => Container(
                padding: EdgeInsets.all(5),
                child: Text(searchedNames[index]),
              ),
            ),
          ),
        ],
      ),
    );
  }
}


推荐阅读