I am currently trying to create a search function to filter a constitution on the Home Page by using the name[title]. I used the CupertinoSearchTextField class. The constitutions posted will be displayed when the homepage, the search bar will allow users to search for a specific constitution.
Code of search widget container
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
class SearchBar extends StatelessWidget {
const SearchBar({super.key});
@override
Widget build(BuildContext context) {
return Container(
margin: const EdgeInsets.symmetric(vertical: 30),
padding: const EdgeInsets.symmetric(horizontal: 20, vertical: 8),
child: CupertinoSearchTextField(
onChanged: ((value) {
}),
autofocus: true,
itemColor: Colors.black,
itemSize: 20,
backgroundColor: const Color.fromARGB(255, 185, 204, 218),
placeholderStyle: const TextStyle(
color: Colors.black,
fontSize: 18,
),
),
);
}
}
Code of the Home Page
// ignore_for_file: prefer_const_constructors
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:google_fonts/google_fonts.dart';
import 'package:project/controller/constitution_controller.dart';
import 'package:project/model/constitution_model.dart';
import 'package:project/screens/branch_page.dart';
import 'package:project/widgets/drawer_widget.dart';
import 'package:project/widgets/searchbar.dart';
import 'package:project/widgets/shimmer_grid_card.dart';
import 'package:shimmer/shimmer.dart';
import '../widgets/constitution_card.dart';
class HomePage extends StatefulWidget {
const HomePage({Key? key}) : super(key: key);
@override
State<HomePage> createState() => _HomePageState();
}
class _HomePageState extends State<HomePage> {
final ConstitutionController constitutionController = Get.find();
@override
Widget build(BuildContext context) {
final double height = MediaQuery.of(context).size.height;
return Scaffold(
appBar: AppBar(
backgroundColor: const Color(0xFF0B3C5D),
elevation: 0.0,
),
drawer: DrawerWidget(),
body: Stack(children: [
Container(
height: height * 0.45,
decoration: const BoxDecoration(
color: Color(0xFF0B3C5D),
// image: DecorationImage(
// image: ExactAssetImage('images/hpb.png'))
),
),
SafeArea(
child: Padding(
padding: const EdgeInsets.symmetric(horizontal: 20),
child: Column(
children: [
Text(
'Legal Companion',
style: GoogleFonts.firaSans(
textStyle: const TextStyle(
color: Colors.white,
fontSize: 32,
),
),
),
// The Search bar
const SearchBar(),
const SizedBox(
height: 70,
),
Flexible(
child: Obx(() {
if (constitutionController.isLoading.value) {
return GridView.builder(
itemBuilder: (_, __) {
return Shimmer.fromColors(
baseColor: Colors.grey[300]!,
highlightColor: Colors.grey[100]!,
period: Duration(seconds: 2),
enabled: constitutionController.isLoading.value,
child: ShimmerGridCard());
},
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 2),
);
} else {
return GridView.builder(
itemCount:
constitutionController.constitutionList.length,
gridDelegate:
SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 2),
itemBuilder: (context, index) {
Constitution constitution =
constitutionController.constitutionList[index];
return InkWell(
onTap: (() {
Get.to(
BranchPage(constitutionId: constitution));
}),
child: ConstitutionCard(constitutionController
.constitutionList[index]));
});
}
}),
),
],
),
),
),
]),
);
}
}
The Constitution Card Code. The various cards on the home page
// ignore_for_file: prefer_const_constructors
import 'package:flutter/material.dart';
import 'package:flutter_svg/flutter_svg.dart';
import 'package:google_fonts/google_fonts.dart';
import 'package:project/model/constitution_model.dart';
class ConstitutionCard extends StatelessWidget {
final Constitution constitution;
const ConstitutionCard(this.constitution, {super.key});
@override
Widget build(BuildContext context) {
return Card(
color: Colors.blueAccent[80],
child: Padding(
padding: const EdgeInsets.all(8.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Spacer(),
SizedBox(
height: 85,
width: double.infinity,
child: SvgPicture.asset("assets/images/ug.svg"),
),
const Spacer(),
Text(
constitution.title,
textAlign: TextAlign.center,
style: GoogleFonts.openSans(
textStyle: const TextStyle(
fontSize: 16,
fontWeight: FontWeight.w700,
),
),
),
Spacer()
],
),
),
);
}
}
The Code of the Controller
import 'dart:convert';
import 'package:get/state_manager.dart';
import 'package:project/model/constitution_model.dart';
import 'package:project/services/service.dart';
class ConstitutionController extends GetxController {
var isLoading = false.obs;
RxList constitutionList = <Constitution>[].obs;
RxList chapterList = <Chapter>[].obs;
RxList sectionList = <Section>[].obs;
//Causes the objects to appear on debugging
@override
void onInit() {
getConstitutions("");
super.onInit();
}
void getConstitutions(String search) async {
try {
isLoading(true);
dynamic response = await HttpService.getConstitutions(search);
if (response.statusCode == 200) {
List<dynamic> body = jsonDecode(response.body);
List<Constitution> constitutions = body
.map(
(dynamic item) => Constitution.fromJson(item),
)
.toList();
constitutionList(constitutions);
isLoading(false);
}
} catch (err) {
isLoading(false);
} finally {
isLoading(false);
}
}
Future getChapters(String constitutionId) async {
try {
isLoading(true);
dynamic response = await HttpService.getChapters(constitutionId);
if (response.statusCode == 200) {
List<dynamic> body = jsonDecode(response.body);
List<Chapter> chapters = body
.map(
(dynamic item) => Chapter.fromJson(item),
)
.toList();
chapterList(chapters);
isLoading(false);
}
} catch (err) {
// print(err);
isLoading(false);
} finally {
isLoading(false);
}
}
Future getSections(String constitutionId, String chapterId) async {
try {
isLoading(true);
dynamic response =
await HttpService.getSections(constitutionId, chapterId);
if (response.statusCode == 200) {
List<dynamic> body = jsonDecode(response.body);
List<Section> sections = body
.map(
(dynamic item) => Section.fromJson(item),
)
.toList();
sectionList(sections);
// print(sectionList);
isLoading(false);
}
} catch (err) {
// print("errorr hhhherrrrrrrhhhh");
// print(err);
isLoading(false);
}
finally {
isLoading(false);
}
}
}
CodePudding user response:
As far as I can understand, you are trying to achieve something like below listview search.
If yes, then You have to use some state management, so that you can handle the loading, and filtering state handling. You can use BloC, valueListenableBuilder, or something like that.
E.g. ValueListenableBuilder https://blog.devgenius.io/flutter-valuenotifier-and-valuelistenablebuilder-41c700315786
In your case, you have to notify in onChange callback of CupertinoSearchTextField.
CodePudding user response:
import 'package:flutter/material.dart';
import 'package:flutter/src/widgets/container.dart';
import 'package:flutter/src/widgets/framework.dart';
class SearchBarWidget extends StatefulWidget {
const SearchBarWidget({super.key});
@override
State<SearchBarWidget> createState() => _SearchBarWidgetState();
}
class _SearchBarWidgetState extends State<SearchBarWidget> {
List<String> list = ["Arshad", "khan", "junaid", "Babar", "Tariq", "Mobile"];
String search = "";
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: TextField(
onChanged: (value) {
setState(() {
search = value;
});
},
),
),
body: ListView.builder(
itemCount: list.length,
itemBuilder: (context, index) {
if (search.isEmpty) {
return ListTile(
title: Text(list[index]),
);
}
if (list[index].toLowerCase().contains(search)) {
return ListTile(
title: Text(list[index]),
);
}
return Container();
},
),
);
}
}
Note: This is easy method