I have implemented youtube like search bar, but I need to use twice in a same page, but the controller's instances are same so they are acting as one controller. Please guide me how to get multiple instance of the same controller.
class AddFamilyHistoryPage extends GetView<AddFamilyHistoryController> {
const AddFamilyHistoryPage({super.key});
@override
Widget build(BuildContext context) {
return Scaffold(
resizeToAvoidBottomInset: true,
appBar: getAppBar1(
"Family History",
),
body: Obx(() => SingleChildScrollView(
child: Padding(
padding: const EdgeInsets.only(left: 20, right: 20, top: 16),
child: Column(
children: [
getTextFiled(
lableText: 'Name',
hintText: 'James',
hintColor: color_5F6063,
backgroundColor: colorF5F9EC,
keyboardType: TextInputType.text,
isRoundedCorner: true,
borderColor: fontGreen,
controller: controller.fullNameController,
),
const SizedBox(
height: 16,
),
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Padding(
padding: const EdgeInsets.only(left: 15.0, bottom: 6.0),
child: Text("Relationship",
style: GoogleFonts.roboto(
fontWeight: FontWeight.w500,
fontSize: 12.0,
color: color_5F6063)),
),
const SizedBox(
height: 4,
),
YouTubeSearchBar(
youTubeSearchBarController: controller.youTubeSearchBarController2,
Suggestions: controller.items),
const SizedBox(
height: 16,
),
controller.isProfileExpand
? Container(
width: MediaQuery.of(context).size.width,
decoration: const BoxDecoration(
color: white,
borderRadius:
BorderRadius.all(Radius.circular(12)),
),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
...List.generate(
controller.items.length,
(index) => Padding(
padding: const EdgeInsets.all(16),
child: Text(
controller.items[index],
style: GoogleFonts.roboto(
fontSize: 14,
fontWeight: FontWeight.w400,
color: color_858D9D),
),
))
],
),
)
: const SizedBox(),
const SizedBox(
height: 16,
),
Row(
children: [
Text("Person is",
style: GoogleFonts.roboto(
fontWeight: FontWeight.w500,
fontSize: 12.0,
color: color_5F6063)),
const SizedBox(
width: 16,
),
Container(
height: 40,
width: 167,
padding: const EdgeInsets.all(4),
decoration: BoxDecoration(
color: colorC2C6CE.withOpacity(0.5),
borderRadius:
const BorderRadius.all(Radius.circular(5)),
border: Border.all(color: color_858D9D)),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
controller.isDeceased
? Container(
height: 32,
width: 92,
decoration: const BoxDecoration(
color: colorE04141,
borderRadius: BorderRadius.all(
Radius.circular(5)),
),
alignment: Alignment.center,
child: Text("Deceased",
style: GoogleFonts.roboto(
fontWeight: FontWeight.w400,
fontSize: 14.0,
color: white)),
)
: GestureDetector(
onTap: () {
controller.setDeceased = true;
},
child: Padding(
padding:
const EdgeInsets.only(left: 12),
child: Text("Deceased",
style: GoogleFonts.roboto(
fontWeight: FontWeight.w400,
fontSize: 14.0,
color: color_858D9D)),
),
),
!controller.isDeceased
? Container(
height: 32,
width: 61,
decoration: const BoxDecoration(
color: fontGreen,
borderRadius: BorderRadius.all(
Radius.circular(5)),
),
alignment: Alignment.center,
child: Text("Alive",
style: GoogleFonts.roboto(
fontWeight: FontWeight.w400,
fontSize: 14.0,
color: white)),
)
: GestureDetector(
onTap: () {
controller.setDeceased = false;
},
child: Padding(
padding:
const EdgeInsets.only(right: 12),
child: Text("Alive",
style: GoogleFonts.roboto(
fontWeight: FontWeight.w400,
fontSize: 14.0,
color: color_858D9D)),
),
)
],
),
)
],
),
const SizedBox(
height: 16,
),
SizedBox(
height: 150,
child: ListView.builder(
itemCount: controller.tempDisease.length,
itemBuilder: (BuildContext context, int index) {
return DiseaseCard(
disease: controller.tempDisease[index],
);
},
// children: const [
// DiseaseCard(),
// ],
)),
Container(
width: MediaQuery.of(context).size.width,
margin: const EdgeInsets.only(bottom: 16),
padding: const EdgeInsets.all(16),
decoration: BoxDecoration(
color: colorFCF7EE,
borderRadius: BorderRadius.circular(12),
),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text(
"Diseases",
style: GoogleFonts.roboto(
fontSize: 14,
fontWeight: FontWeight.w500,
color: color_5F6063,
),
),
Row(
children: [
IconButton(
padding: const EdgeInsets.only(
left: 0, top: 16, bottom: 16),
onPressed: () {
if (controller
.youTubeSearchBarController
.searchController
.text
.isNotEmpty)
controller.addDisease();
},
icon: Image.asset(
getAssetsPNGImg('right'),
width: 16,
height: 12,
)),
Text(
"Done",
style: GoogleFonts.roboto(
fontSize: 14,
fontWeight: FontWeight.w500,
color: fontGreen,
decoration: TextDecoration.underline),
),
],
),
],
),
const SizedBox(
height: 16,
),
Padding(
padding: const EdgeInsets.only(
left: 15.0, bottom: 6.0),
child: Text('Disease Name',
style: GoogleFonts.roboto(
fontWeight: FontWeight.w500,
fontSize: 12.0,
color: color_5F6063)),
),
Obx(() {
var output = controller.dataState.value;
switch (output.state) {
case (UiState.SUCCESS):
{
controller.dieseaseList = output.data
?.map((disease) => disease.name!)
.toList() ??
[];
return YouTubeSearchBar(
youTubeSearchBarController:
controller.youTubeSearchBarController,
Suggestions: controller.dieseaseList,
hintText: 'Select Disease',
);
}
case UiState.EMPTY:
return const Text(
'No Disease present in the catalogue');
case UiState.LOADING:
return const CircularProgressIndicator();
case UiState.ERROR:
return const Text('Error');
}
}),
const SizedBox(
height: 16,
),
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
"Cause of Death",
style: GoogleFonts.roboto(
fontSize: 12,
fontWeight: FontWeight.w500,
color: color_858D9D,
),
),
const SizedBox(
height: 8,
),
SizedBox(
height: 18,
width: 18,
child: getCheckBox(
checked: controller.isCauseOfDeath.value,
onChanged: (bool? value) {
controller.isCauseOfDeath.value =
!controller.isCauseOfDeath.value;
},
),
),
],
),
const SizedBox(
height: 16,
),
getTextFiled(
lableText: 'Additional Details',
hintText: 'Hypoglycemia, High Cholesterol',
hintColor: color_5F6063,
backgroundColor: colorFCF7EE,
keyboardType: TextInputType.text,
isRoundedCorner: true,
borderColor: colorF9A826,
controller:
controller.additionalDetailsController),
],
),
),
const SizedBox(
height: 16,
),
SizedBox(
height: 70.0,
width: 90.w,
child: Padding(
padding: const EdgeInsets.only(
left: 25.0, right: 25.0, bottom: 20.0),
child: ButtonView(
radius: 4.0,
bgColor: fontYellow,
borderColor: fontYellow,
btnName: 'Submit',
txtColor: white,
onButtonTap: () {
// Get.toNamed(Routes.ADD_FAMILY_HISTORY);
},
),
),
),
],
)
],
),
),
)),
);
}
}
and here is the controller code snippet for youtube search bar instance
YouTubeSearchBarController youTubeSearchBarController =
Get.put(YouTubeSearchBarController());
YouTubeSearchBarController youTubeSearchBarController2 =
Get.put(YouTubeSearchBarController(),tag: '1');
and here is the code for youtube search bar itself
import 'package:autocomplete_textfield/autocomplete_textfield.dart';
import 'package:ekikrit_patient/app/component/checkbox.dart';
import 'package:flutter/material.dart';
import 'package:get/get.dart';
class YouTubeSearchBarController extends GetxController {
final searchController = TextEditingController();
final focusNode = FocusNode();
RxBool isChecked = false.obs;
@override
void onInit() {
super.onInit();
}
@override
void onClose() {
searchController.dispose();
focusNode.dispose();
super.onClose();
}
}
class YouTubeSearchBar extends GetView<YouTubeSearchBarController> {
final YouTubeSearchBarController youTubeSearchBarController;
List<String> Suggestions;
final String? hintText;
final Color? textColor;
final TextStyle? hintStyle;
YouTubeSearchBar({
super.key,
required this.youTubeSearchBarController,
required this.Suggestions,
this.hintText,
this.textColor,
this.hintStyle,
});
@override
Widget build(BuildContext context) {
return SingleChildScrollView(
child: Padding(
padding: EdgeInsets.only(
top: 5,
left: 5,
right: 5,
bottom: MediaQuery.viewInsetsOf(context).bottom,
),
child: Row(
children: [
Expanded(
child: AutoCompleteTextField<String>(
key: GlobalKey<AutoCompleteTextFieldState<String>>(),
clearOnSubmit: false,
suggestionsAmount: 50,
style: TextStyle(color: textColor),
suggestions: Suggestions,
keyboardType: TextInputType.text,
controller: controller.searchController,
focusNode: controller.focusNode,
decoration: InputDecoration(
hintText: hintText ?? '',
hintStyle: hintStyle,
filled: true,
fillColor: Color(0xFFFFF7EB),
enabledBorder: const OutlineInputBorder(
borderRadius: BorderRadius.all(Radius.circular(8.0)),
borderSide:
BorderSide(color: Color(0xFFF9A826), width: 2.0)),
disabledBorder: const OutlineInputBorder(
borderRadius: BorderRadius.all(Radius.circular(8.0)),
borderSide:
BorderSide(color: Color(0xFFF9A826), width: 2.0)),
focusedBorder: const OutlineInputBorder(
borderRadius: BorderRadius.all(Radius.circular(8.0)),
borderSide:
BorderSide(color: Color(0xFFF9A826), width: 2.0)),
errorBorder:const OutlineInputBorder(
borderRadius: BorderRadius.all(Radius.circular(8.0)),
borderSide:
BorderSide(color: Color(0xFFF9A826), width: 200.0)) ,
border: const OutlineInputBorder(
borderRadius: BorderRadius.all(Radius.circular(8.0)),
borderSide:
BorderSide(color: Color(0xFFF9A826), width: 20.0)),
prefixIcon: Icon(Icons.search),
),
itemBuilder: (context, suggestion) => ListTile(
title: Text(suggestion),
leading: SizedBox(
width: 15,
height: 15,
child:
getCheckBox(
checked: controller.searchController.text == suggestion,
onChanged: (value) {
controller.searchController.text =
controller.isChecked.value ? '' : suggestion;
},
)),
),
itemFilter: (item, input) {
if (input.isBlank!) return true;
return item.toLowerCase().startsWith(input.toLowerCase());
},
itemSorter: (a, b) => a.compareTo(b),
itemSubmitted: (item) {
if (item.isEmpty) {
// Handle when an empty text is submitted (show all suggestions)
print('Show all suggestions');
} else {
print('Selected item: $item');
}},), ),],), ), ); }
I want the two youtube search bar controller should have different instances of the youtubseSearchBarController so that the values in the texfield don't collide.
The image here show two youtube search bar having value GRANDPARENTS2.
You can you the Create of Getx for creating the controller dependency. As the name implies, it will "create" your dependency! Similar to Get.put(), it also calls the internal method insert to instancing. But permanent became true and isSingleton became false. Read more here
You can use Get.create like this in your scenario:
// This will inject the dependency:
Get.create<YouTubeSearchBarController>(() => YouTubeSearchBarController());
// and as soon as you call this the Get.find it will always return new instances of the controller:
final youTubeController1 = Get.find<YouTubeSearchBarController>();
final youTubeController2 = Get.find<YouTubeSearchBarController>();
print(identical(youTubeController1, youTubeController2)); // false
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With