如何在 Getx Flutter 中使用控制器的多个实例

问题描述 投票:0回答:1

我已经实现了类似 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 搜索栏。

flutter controller frontend singleton flutter-getx
1个回答
0
投票

您可以使用

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
© www.soinside.com 2019 - 2024. All rights reserved.