我已经实现了类似 youtube 的搜索栏,但我需要在同一页面中使用两次,但控制器的实例是相同的,因此它们充当一个控制器。请指导我如何获取同一控制器的多个实例。
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);
},
),
),
),
],
)
],
),
),
)),
);
}
}
这是 YouTube 搜索栏实例的控制器代码片段
YouTubeSearchBarController youTubeSearchBarController =
Get.put(YouTubeSearchBarController());
YouTubeSearchBarController youTubeSearchBarController2 =
Get.put(YouTubeSearchBarController(),tag: '1');
这是 YouTube 搜索栏本身的代码
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');
}},), ),],), ), ); }
我希望两个 youtube 搜索栏控制器应该具有不同的 youtubseSearchBarController 实例,以便文本字段中的值不会发生冲突。 此处的图像显示了两个具有值为 GRANDPARENTS2 的 YouTube 搜索栏。
您可以使用
Create
的 Getx
来创建控制器依赖项。顾名思义,它将“创建”您的依赖关系!与Get.put()类似,也是调用内部方法insert来实例化。但 permanent 变为 true,而 isSingleton 变为 false。 在这里阅读更多内容
您可以在您的场景中像这样使用 Get.create :
// 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