如何在Flutter中实现姓名搜索功能

huangapple go评论73阅读模式
英文:

how to make name search feature in flutter

问题

这是你提供的代码部分:

List<Data> data = [];
List<Data> allData = [];
List<Data> _foundData = [];

@override
initState() {
_foundData = allData;
super.initState();
}

@override
void dispose() {
_foundData.clear();
super.dispose();
}

void _runFilter(String enteredKeyword) {
List<Data> results = [];
if (enteredKeyword.isEmpty) {
  results = allData;
} else {
  results = allData
      .where(
        (user) => user.name!.toLowerCase().contains(
              enteredKeyword.toLowerCase(),
            ),
      )
       .toList();
 }
 setState(() {
  _foundData = results;
 });
 }

@override
  Widget build(BuildContext context) {
    // ... (其余部分被省略)
  }

如果你有任何关于这段代码的问题或需要进一步的帮助,请随时告诉我。

英文:

I'm having a problem doing a name search, where when I type the name of a user, it doesn't appear the way I want and doesn't filter according to the name I'm looking for.

List<Data> data = [];
List<Data> allData = [];
List<Data> _foundData = [];
@override
initState() {
_foundData = allData;
super.initState();
}
@override
void dispose() {
_foundData.clear();
super.dispose();
}
void _runFilter(String enteredKeyword) {
List<Data> results = [];
if (enteredKeyword.isEmpty) {
results = allData;
} else {
results = allData
.where(
(user) => user.name!.toLowerCase().contains(
enteredKeyword.toLowerCase(),
),
)
.toList();
}
setState(() {
_foundData = results;
});
}`
@override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: backgroundColor,
appBar: const PreferredSize(
preferredSize: Size.fromHeight(kToolbarHeight),
child: CustomAppbar(
title: 'Dosen',
),
),
body: Center(
child: Padding(
padding: const EdgeInsets.only(
left: 16,
top: 16,
right: 16,
),
child: Column(
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Padding(
padding: const EdgeInsets.only(bottom: 8),
child: TextField(
onChanged: (value) => _runFilter(value),
decoration: InputDecoration(
enabledBorder: OutlineInputBorder(
borderSide: BorderSide(
width: 1,
color: Colors.grey.shade300,
),
borderRadius: BorderRadius.circular(10),
),
focusedBorder: OutlineInputBorder(
borderSide: const BorderSide(
width: 1,
color: Color.fromARGB(255, 255, 255, 255),
),
borderRadius: BorderRadius.circular(10),
),
hintText: 'Cari nama dosen...',
fillColor: const Color.fromARGB(255, 255, 255, 255),
filled: true,
hintStyle: TextStyle(
color: greyColor,
),
suffixIcon: Icon(
Icons.search,
color: greyColor,
),
),
),
),
FutureBuilder<List<Data>>(
future: ListDosenProvider.getDosen(),
builder: (context, snapshot) {
if (snapshot.hasData) {
if (snapshot.connectionState == ConnectionState.done) {
return Expanded(
child: ListView.builder(
physics: const BouncingScrollPhysics(),
itemCount: snapshot.data!.length,
// itemCount: allData.length,
// itemCount: _foundData.length,
itemBuilder: (context, index) {
return Padding(
padding: const EdgeInsets.only(top: 14),
child: Container(
width: MediaQuery.of(context).size.width,
decoration: BoxDecoration(
color: Colors.white,
borderRadius: const BorderRadius.all(
Radius.circular(8),
),
boxShadow: [
BoxShadow(
color: Colors.grey.withOpacity(0.2),
spreadRadius: 1,
blurRadius: 9,
offset: const Offset(
1,
2,
),
),
],
),
child: Padding(
padding: const EdgeInsets.all(14),
child: Row(
children: [
Image.asset(
'assets/images/user.png',
width: 50,
),
const SizedBox(
width: 10,
),
Column(
crossAxisAlignment:
CrossAxisAlignment.start,
children: [
Text(
snapshot.data![index].name
.toString(),
style: bold6,
),
Text(
snapshot.data![index].prodi
.toString(),
style: regular6,
),
const SizedBox(
width: 8,
),
const SizedBox(
height: 5,
),
SizedBox(
height: 30,
width: 90,
child: ElevatedButton.icon(
onPressed: () {
Navigator.of(context).pop();
// ignore: deprecated_member_use
launch(
'mailto:${snapshot.data![index].email.toString()}',
);
},
icon: Icon(
Icons.mail,
size: 17,
color: primaryColor,
),
label: Text('Email',
style: bold6.copyWith(
color: primaryColor,
)),
style: ElevatedButton.styleFrom(
backgroundColor: const Color(
0xffC5D5FF,
),
),
),
),
],
),
],
),
),
),
);
},
),
);
}
} else if (snapshot.hasError) {
return Expanded(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
// crossAxisAlignment: CrossAxisAlignment.center,
children: [
Center(
child: Image.asset(
'assets/images/server.png',
height: 100,
),
),
const SizedBox(
height: 20,
),
Text(
'Upsss... Server error!',
style: regular4,
)
],
),
);
}
return Expanded(
child: Center(
child: CircularProgressIndicator(color: primaryColor),
),
);
},
),
],
),
),
),
);
}

I've been looking for a way and doing it according to the instructions above but it still doesn't work when I do a name search
enter image description here

答案1

得分: 1

你必须使用 _foundData 来列出数据。在某些情况下,如果用户在加载之前输入搜索,可能会无法正常工作。因此,我使用 TextEditingController 在每次构建时过滤搜索结果,以便我们可以保留用户输入。

将你的代码替换为以下内容:

List<Data> allData = [];
List<Data> _foundData = [];
final searchController = TextEditingController();

@override
void dispose() {
  _foundData.clear();
  super.dispose();
}

void _runFilter(String enteredKeyword) {
  List<Data> results = [];
  if (enteredKeyword.trim().isEmpty) {
    results = allData;
  } else {
    results = allData
        .where(
          (user) => user.name!.toLowerCase().contains(
                enteredKeyword.trim().toLowerCase(),
              ),
        )
        .toList();
  }
  _foundData = results;
}

@override
Widget build(BuildContext context) {
  return Scaffold(
    backgroundColor: backgroundColor,
    appBar: const PreferredSize(
      preferredSize: Size.fromHeight(kToolbarHeight),
      child: CustomAppbar(
        title: 'Dosen',
      ),
    ),
    body: Center(
      child: Padding(
        padding: const EdgeInsets.only(
          left: 16,
          top: 16,
          right: 16,
        ),
        child: Column(
          crossAxisAlignment: CrossAxisAlignment.center,
          children: [
            Padding(
              padding: const EdgeInsets.only(bottom: 8),
              child: TextField(
                onChanged: (value) => setState(() {}),
                controller: searchController,
                decoration: InputDecoration(
                  enabledBorder: OutlineInputBorder(
                    borderSide: BorderSide(
                      width: 1,
                      color: Colors.grey.shade300,
                    ),
                    borderRadius: BorderRadius.circular(10),
                  ),
                  focusedBorder: OutlineInputBorder(
                    borderSide: const BorderSide(
                      width: 1,
                      color: Color.fromARGB(255, 255, 255, 255),
                    ),
                    borderRadius: BorderRadius circular(10),
                  ),
                  hintText: 'Cari nama dosen...',
                  fillColor: Color.fromARGB(255, 255, 255, 255),
                  filled: true,
                  hintStyle: TextStyle(
                    color: greyColor,
                  ),
                  suffixIcon: Icon(
                    Icons.search,
                    color: greyColor,
                  ),
                ),
              ),
            ),
            FutureBuilder<List<Data>>(
              future: ListDosenProvider.getDosen(),
              builder: (context, snapshot) {
                if (snapshot.hasData) {
                  if (snapshot.connectionState == ConnectionState.done) {
                    allData = snapshot.data!;
                    _runFilter(searchController.text);
                    return Expanded(
                      child: ListView.builder(
                        physics: BouncingScrollPhysics(),
                        itemCount: _foundData.length,
                        itemBuilder: (context, index) {
                          return Padding(
                            padding: const EdgeInsets.only(top: 14),
                            child: Container(
                              width: MediaQuery.of(context).size.width,
                              decoration: BoxDecoration(
                                color: Colors.white,
                                borderRadius: BorderRadius.all(
                                  Radius.circular(8),
                                ),
                                boxShadow: [
                                  BoxShadow(
                                    color: Colors.grey.withOpacity(0.2),
                                    spreadRadius: 1,
                                    blurRadius: 9,
                                    offset: Offset(
                                      1,
                                      2,
                                    ),
                                  ),
                                ],
                              ),
                              child: Padding(
                                padding: const EdgeInsets.all(14),
                                child: Row(
                                  children: [
                                    Image.asset(
                                      'assets/images/user.png',
                                      width: 50,
                                    ),
                                    SizedBox(
                                      width: 10,
                                    ),
                                    Column(
                                      crossAxisAlignment: CrossAxisAlignment.start,
                                      children: [
                                        Text(
                                          _foundData[index].name.toString(),
                                          style: bold6,
                                        ),
                                        Text(
                                          _foundData[index].prodi.toString(),
                                          style: regular6,
                                        ),
                                        SizedBox(
                                          width: 8,
                                        ),
                                        SizedBox(
                                          height: 5,
                                        ),
                                        SizedBox(
                                          height: 30,
                                          width: 90,
                                          child: ElevatedButton.icon(
                                            onPressed: () {
                                              Navigator.of(context).pop();
                                              launch(
                                                'mailto:${_foundData[index].email.toString()}',
                                              );
                                            },
                                            icon: Icon(
                                              Icons.mail,
                                              size: 17,
                                              color: primaryColor,
                                            ),
                                            label: Text('Email',
                                                style: bold6.copyWith(
                                                  color: primaryColor,
                                                )),
                                            style: ElevatedButton.styleFrom(
                                              backgroundColor: Color(0xffC5D5FF),
                                            ),
                                          ),
                                        ),
                                      ],
                                    ),
                                  ],
                                ),
                              ),
                            ),
                          );
                        },
                      ),
                    );
                  }
                } else if (snapshot.hasError) {
                  return Expanded(
                    child: Column(
                      mainAxisAlignment: MainAxisAlignment.center,
                      children: [
                        Center(
                          child: Image.asset(
                            'assets/images/server.png',
                            height: 100,
                          ),
                        ),
                        SizedBox(
                          height: 20,
                        ),
                        Text(
                          'Upsss... Server error!',
                          style: regular4,
                        )
                      ],
                    ),
                  );
                }
                return Expanded(
                  child: Center(
                    child: CircularProgressIndicator(color: primaryColor),
                  ),
                );
              },
            ),
          ],
        ),
      ),
    ),
  );
}

希望这有所帮助。

英文:

You have to use _foundData to list data. In some case, if use enters search before load that may not work. So I filter the search result on every build by using TextEditingController, so that we can persist user input.

Replace you code with following..


List&lt;Data&gt; allData = [];
List&lt;Data&gt; _foundData = [];
final searchController = TextEditingController();
@override
void dispose() {
_foundData.clear();
super.dispose();
}
void _runFilter(String enteredKeyword) {
List&lt;Data&gt; results = [];
if (enteredKeyword.trim().isEmpty) {
results = allData;
} else {
results = allData
.where(
(user) =&gt; user.name!.toLowerCase().contains(
enteredKeyword.trim().toLowerCase(),
),
)
.toList();
}
_foundData = results;
}
@override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: backgroundColor,
appBar: const PreferredSize(
preferredSize: Size.fromHeight(kToolbarHeight),
child: CustomAppbar(
title: &#39;Dosen&#39;,
),
),
body: Center(
child: Padding(
padding: const EdgeInsets.only(
left: 16,
top: 16,
right: 16,
),
child: Column(
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Padding(
padding: const EdgeInsets.only(bottom: 8),
child: TextField(
onChanged: (value) =&gt; setState(() {}),
controller: searchController,
decoration: InputDecoration(
enabledBorder: OutlineInputBorder(
borderSide: BorderSide(
width: 1,
color: Colors.grey.shade300,
),
borderRadius: BorderRadius.circular(10),
),
focusedBorder: OutlineInputBorder(
borderSide: const BorderSide(
width: 1,
color: Color.fromARGB(255, 255, 255, 255),
),
borderRadius: BorderRadius.circular(10),
),
hintText: &#39;Cari nama dosen...&#39;,
fillColor: const Color.fromARGB(255, 255, 255, 255),
filled: true,
hintStyle: TextStyle(
color: greyColor,
),
suffixIcon: Icon(
Icons.search,
color: greyColor,
),
),
),
),
FutureBuilder&lt;List&lt;Data&gt;&gt;(
future: ListDosenProvider.getDosen(),
builder: (context, snapshot) {
if (snapshot.hasData) {
if (snapshot.connectionState == ConnectionState.done) {
allData = snapshot.data!;
_runFilter(searchController.text);
return Expanded(
child: ListView.builder(
physics: const BouncingScrollPhysics(),
itemCount: _foundData.length,
// itemCount: allData.length,
// itemCount: _foundData.length,
itemBuilder: (context, index) {
return Padding(
padding: const EdgeInsets.only(top: 14),
child: Container(
width: MediaQuery.of(context).size.width,
decoration: BoxDecoration(
color: Colors.white,
borderRadius: const BorderRadius.all(
Radius.circular(8),
),
boxShadow: [
BoxShadow(
color: Colors.grey.withOpacity(0.2),
spreadRadius: 1,
blurRadius: 9,
offset: const Offset(
1,
2,
),
),
],
),
child: Padding(
padding: const EdgeInsets.all(14),
child: Row(
children: [
Image.asset(
&#39;assets/images/user.png&#39;,
width: 50,
),
const SizedBox(
width: 10,
),
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
_foundData[index].name.toString(),
style: bold6,
),
Text(
_foundData[index].prodi.toString(),
style: regular6,
),
const SizedBox(
width: 8,
),
const SizedBox(
height: 5,
),
SizedBox(
height: 30,
width: 90,
child: ElevatedButton.icon(
onPressed: () {
Navigator.of(context).pop();
// ignore: deprecated_member_use
launch(
&#39;mailto:${_foundData[index].email.toString()}&#39;,
);
},
icon: Icon(
Icons.mail,
size: 17,
color: primaryColor,
),
label: Text(&#39;Email&#39;,
style: bold6.copyWith(
color: primaryColor,
)),
style: ElevatedButton.styleFrom(
backgroundColor: const Color(
0xffC5D5FF,
),
),
),
),
],
),
],
),
),
),
);
},
),
);
}
} else if (snapshot.hasError) {
return Expanded(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
// crossAxisAlignment: CrossAxisAlignment.center,
children: [
Center(
child: Image.asset(
&#39;assets/images/server.png&#39;,
height: 100,
),
),
const SizedBox(
height: 20,
),
Text(
&#39;Upsss... Server error!&#39;,
style: regular4,
)
],
),
);
}
return Expanded(
child: Center(
child: CircularProgressIndicator(color: primaryColor),
),
);
},
),
],
),
),
),
);
}

I hope this helps.

huangapple
  • 本文由 发表于 2023年2月27日 09:51:43
  • 转载请务必保留本文链接:https://go.coder-hub.com/75576183.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定