【问题标题】:how do i add a search bar for a listview.Builder with a json file?如何使用 json 文件为 listview.Builder 添加搜索栏?
【发布时间】:2021-02-05 11:39:28
【问题描述】:

在我的应用程序 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 文件中的列表名称是: 马丁 麦克风 詹姆斯

当我开始输入“M”时,我会看到一个列表 马丁 迈克。

有什么建议吗?

谢谢

【问题讨论】:

  • 搜索和列表视图必须通过任何状态管理进行通信。你如何管理你的状态。 bloc 库、提供程序或其他什么或什么都没有?
  • @Error280MonkeyFound 我不知道如何开始做搜索栏,只是因为我不知道如何让他们“交流”
  • 我不在比赛前。我会尝试在 2-3 小时内发布。

标签: json flutter searchbar


【解决方案1】:

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

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

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]),
              ),
            ),
          ),
        ],
      ),
    );
  }
}

【讨论】:

  • @Benn,请随时要求澄清。
  • 我理解你的解释。即使不搜索任何内容,我也希望看到我的姓名列表。
  • 为此,您可以将 searchedNames 的初始数据设置为 allNames。此外,如果您希望在搜索为空时显示所有名称,请添加 else 部分 searchChanged 方法。我已经明智地编辑了代码。请检查。
猜你喜欢
  • 2021-07-12
  • 1970-01-01
  • 1970-01-01
  • 2021-12-23
  • 2020-08-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多