【问题标题】:Listview.builder with Getx state management带有 Getx 状态管理的 Listview.builder
【发布时间】:2021-11-08 03:21:49
【问题描述】:

我正在字控制器类中从数据库中读取数据。然后我使用 listview.builder 在 UI 中列出数据。当您在同一页面中添加数据时,它不会同时添加到列表中。我正在使用 getx,但我无法成功执行此操作。我用 controller.addNote() 添加。我正在使用 historyWordList 列出数据。我不知道如何使用obx和obs。我在这里分享相关代码。

你能帮帮我吗?

代码在这里: 控制器类:

class WordController extends GetxController {
  TextEditingController controllerInput1 = TextEditingController();
  TextEditingController controllerInput2 = TextEditingController();
  var items = <Word>[].obs;
  final translator = GoogleTranslator();


  ekle(Word word) async {
    var val = await WordRepo().add(word);
    showDilog("Kayıt Başarılı");
    return val;
  }

  updateWord(Word word) async {
    var val = await WordRepo().update(word);
    showDilog("Kayıt Başarılı");
    return val;
  }

  deleteWord(int? id) async {
    var val = await WordRepo().deleteById(id!);
    return val;
  }

  getir() async {
    var list = await WordRepo().getAll();
    print(list);
    // update();
    return list;

  }

  translateLanguage(String newValue) async {
    if(newValue==null || newValue.length==0){
      return;
    }
    List list=["I","i"];
    if(newValue.length==1 && !list.contains(newValue)){
      return;
    }

    var translate = await translator
        .translate(newValue, from: 'en', to: 'tr');

       controllerInput2.text = translate.toString();
        //addNote();
    return translate;
  }
  showDilog(String message) {
    Get.defaultDialog(title: "Bilgi", middleText: message);
  }

    addNote() async {
      var word =
          Word(wordEn: controllerInput1.text, wordTr: controllerInput2.text);
      await ekle(word);

      clear();

  }
clear(){
  controllerInput2.clear();
  controllerInput1.clear();
}
  updateNote() async {
    var word =
        Word(wordEn: controllerInput1.text, wordTr: controllerInput2.text);
    await updateWord(word);
    await getir();
    update();
  }
}

用户界面页面:

class MainPage extends StatelessWidget {
  String _firstLanguage = "English";
  String _secondLanguage = "Turkish";

  WordController controller = Get.put(WordController());
  final _formKey = GlobalKey<FormState>();

  @override
  Widget build(BuildContext context) {
    controller.getir();

    return Scaffold(
      drawer: _drawer,
      backgroundColor: Colors.blueAccent,
      appBar: _appbar,
      body: _bodyScaffold,
      floatingActionButton: _floattingActionButton,
    );
  }

  SingleChildScrollView get _bodyScaffold {
    return SingleChildScrollView(
      child: Column(
        children: [
          chooseLanguage,
          translateTextView,
          //futureBuilder,
        ],
      ),
    );
  }

  AppBar get _appbar {
    return AppBar(
      backgroundColor: Colors.blueAccent,
      centerTitle: true,
      title: Text("TRANSLATE"),
      elevation: 0.0,
    );
  }



  get chooseLanguage => Container(
    height: 55.0,
    decoration: buildBoxDecoration,
    child: Row(
      mainAxisAlignment: MainAxisAlignment.start,
      crossAxisAlignment: CrossAxisAlignment.center,
      children: <Widget>[
        firstChooseLanguage,
        changeLanguageButton,
        secondChooseLanguage,
      ],
    ),
  );

  get buildBoxDecoration {
    return BoxDecoration(
      color: Colors.white,
      border: Border(
        bottom: BorderSide(
          width: 3.5,
          color: Colors.grey,
        ),
      ),
    );
  }
  refreshList() {
    controller.getir();
  }
  get changeLanguageButton {
    return Material(
      color: Colors.white,
      child: IconButton(
        icon: Icon(
          Icons.wifi_protected_setup_rounded,
          color: Colors.indigo,
          size: 30.0,
        ),
        onPressed: () {},
      ),
    );
  }

  get secondChooseLanguage {
    return Expanded(
      child: Material(
        color: Colors.white,
        child: InkWell(
          onTap: () {},
          child: Center(
            child: Text(
              this._secondLanguage,
              style: TextStyle(
                color: Colors.blue[600],
                fontSize: 22.0,
              ),
            ),
          ),
        ),
      ),
    );
  }

  get firstChooseLanguage {
    return Expanded(
      child: Material(
        color: Colors.white,
        child: InkWell(
          onTap: () {},
          child: Center(
            child: Text(
              this._firstLanguage,
              style: TextStyle(
                color: Colors.blue[600],
                fontSize: 22.0,
              ),
            ),
              ),
            ),
          ),
        );
      }
    
      get translateTextView => Column(
        children: [
          Card(
            shape: RoundedRectangleBorder(
              borderRadius: BorderRadius.all(Radius.circular(8.0)),
            ),
            margin: EdgeInsets.only(left: 2.0, right: 2.0, top: 4.0),
            child: _formTextField,
          ),
          Container(
            height: 300,
            child: historyWordList,
          )
        ],
      );
    
      get _formTextField {
        return Form(
          key: _formKey,
          child: Column(
            mainAxisAlignment: MainAxisAlignment.center,
            children: [
              Container(
                color: Colors.white30,
                height: 120.0,
                padding: EdgeInsets.only(left: 16.0, top: 8.0, bottom: 8.0),
                child: Row(
                  mainAxisAlignment: MainAxisAlignment.spaceBetween,
                  children: <Widget>[
                    textFormFieldEntr,
                    favoriIconButton,
                  ],
                ),
              ),
              textFormField,
            ],
          ),
        );
      }
    
      get textFormFieldEntr {
        return Flexible(
          child: Container(
            child: TextFormField(
              onChanged: (text) {
                controller.translateLanguage(text);
              },
              controller: controller.controllerInput1,
              maxLines: 6,
              validator: (controllerInput1) {
                if (controllerInput1!.isEmpty) {
                  return "lütfen bir değer giriniz";
                } else if (controllerInput1.length > 22) {
                  return "en fazla 22 karakter girebilirsiniz";
                }
                return null;
              },
              decoration: InputDecoration(
                hintText: "Enter",
                contentPadding: const EdgeInsets.symmetric(vertical: 5.0),
              ),
            ),
          ),
        );
      }
    
      get textFormField {
        return Container(
          color: Colors.white30,
          height: 120.0,
          padding: EdgeInsets.only(left: 16.0, right: 42.0, top: 8.0, bottom: 8.0),
          child: Container(
            child: TextFormField(
              controller: controller.controllerInput2,
              maxLines: 6,
              validator: (controllerInput2) {
                if (controllerInput2!.length > 22) {
                  return "en fazla 22 karakter girebilirsiniz";
                }
                return null;
              },
              decoration: InputDecoration(
                contentPadding: const EdgeInsets.symmetric(vertical: 5.0),
              ),
            ),
          ),
        );
      }
    
      FutureBuilder<dynamic> get historyWordList {
        return FutureBuilder(
          future: controller.getir(),
          builder: (context, AsyncSnapshot snapShot) {
            if (snapShot.hasData) {
              var wordList = snapShot.data;
              return ListView.builder(
                itemCount: wordList.length,
                itemBuilder: (context, index) {
                  return Card(
                    shape: RoundedRectangleBorder(
                      borderRadius: BorderRadius.all(Radius.circular(5.0)),
                    ),
                    margin: EdgeInsets.only(left: 8.0, right: 8.0, top: 0.8),
                    child: Container(
                      color: Colors.white30,
                      height: 70.0,
                      padding: EdgeInsets.only(left: 8.0, top: 8.0, bottom: 8.0),
                      child: Row(
                        crossAxisAlignment: CrossAxisAlignment.start,
                        mainAxisAlignment: MainAxisAlignment.spaceBetween,
                        children: [
                          Column(
                            crossAxisAlignment: CrossAxisAlignment.start,
                            mainAxisAlignment: MainAxisAlignment.spaceAround,
                            children: [
                              firstText(wordList, index),
                              secondText(wordList, index),
                            ],
                          ),
                          historyIconbutton,
                        ],
                      ),
                    ),
                  );
                },
              );
            } else {
              return Center();
            }
          },
        );
      }
    
      IconButton get historyIconbutton {
        return IconButton(
          onPressed: () {},
          icon: Icon(Icons.history),
          iconSize: 30.0,
        );
      }
    
      Text firstText(wordList, int index) {
        return Text(
          "İngilizce: ${wordList[index].wordEn ?? ""}",
          style: TextStyle(
            fontWeight: FontWeight.w600,
          ),
          maxLines: 1,
          overflow: TextOverflow.ellipsis,
        );
      }
    
      Text secondText(wordList, int index) {
        return Text(
          "Türkçe: ${wordList[index].wordTr ?? ""}",
          style: TextStyle(
            fontWeight: FontWeight.w400,
          ),
          maxLines: 1,
          overflow: TextOverflow.ellipsis,
        );
      }
    
      get favoriIconButton {
        return IconButton(
          alignment: Alignment.topRight,
          onPressed: () async {
            bool validatorKontrol = _formKey.currentState!.validate();
            if (validatorKontrol) {
              String val1 = controller.controllerInput1.text;
              String val2 = controller.controllerInput2.text;
              print("$val1 $val2");
              await controller.addNote();
              await refreshList();
            }
            await Obx(() => textFormField(
              controller: controller.controllerInput2,
            ));
            await Obx(() => textFormField(
              controller: controller.controllerInput1,
            ));
          },
          icon: Icon(
            Icons.forward,
            color: Colors.blueGrey,
            size: 36.0,
          ),
        );
      }
    
      FloatingActionButton get _floattingActionButton {
        return FloatingActionButton(
          onPressed: () {
            Get.to(WordListPage());
          },
          child: Icon(
            Icons.app_registration,
            size: 30,
          ),
        );
      }
    
      Drawer get _drawer {
        return Drawer(
          child: ListView(
            // Important: Remove any padding from the ListView.
            padding: EdgeInsets.zero,
            children: <Widget>[
              userAccountsDrawerHeader,
              drawerFavorilerim,
              drawersettings,
              drawerContacts,
            ],
          ),
        );
      }
    
      ListTile get drawerContacts {
        return ListTile(
          leading: Icon(Icons.contacts),
          title: Text("Contact Us"),
          onTap: () {
            Get.back();
          },
        );
      }
    
      ListTile get drawersettings {
        return ListTile(
          leading: Icon(Icons.settings),
          title: Text("Settings"),
          onTap: () {
            Get.back();
          },
        );
      }
    
      ListTile get drawerFavorilerim {
        return ListTile(
          leading: Icon(
            Icons.star,
            color: Colors.yellow,
          ),
          title: Text("Favorilerim"),
          onTap: () {
            Get.to(FavoriListPage());
          },
        );
      }
    
      UserAccountsDrawerHeader get userAccountsDrawerHeader {
        return UserAccountsDrawerHeader(
          accountName: Text("UserName"),
          accountEmail: Text("E-mail"),
          currentAccountPicture: CircleAvatar(
            backgroundColor: Colors.grey,
            child: Text(
              "",
              style: TextStyle(fontSize: 40.0),
            ),
          ),
        );
      }
    }

【问题讨论】:

    标签: flutter listview sqflite flutter-getx


    【解决方案1】:

    Obx 用于告诉被包装的 Widget 在观察值(例如var items = &lt;Word&gt;[].obs;)发生变化时重建。

    所以,基本上你只需要用 Obx 包装你的 ListView.builder,例如:

    Obx(
       () => ListView.builder(
          itemCount: controller.items.legth,
          itemBuilder: (context, index) {
               var wordItem = controller.items[index]; // here is your wordItem ready to be used 
          }
       );
    )
    

    因此,您的列表 ListView 构建器具有来自您的 WordController 的新 wordItems

    【讨论】:

    • 我做不到。你能解释更多吗?我正在使用控制器中的“getir()”方法读取数据。
    • 你不需要让你的getIr方法返回userList,只需简单地让你的方法更新你的items变量,因为你使用obs(观察)@987654327 @.. 因此,每当您的 items 值被更改时.. 包装到 Obx 中的 ListView.builder 将重建
    • 好的,您正在使用 WordRepo().getAll() 来获取 Word 列表,对吗?那么你需要做的只是更新你的items..items.value = await WordRepo().getAll()
    • 在您的items 列表被更新之后.. 它会触发所有 Obx 的子节点进行重建(在这种情况下是您的 ListView.builder)
    • 我会在 getir() 中做 item.value= await Wordrepo.getAll() 吗?我就是这样做的,结果出错了。
    猜你喜欢
    • 2020-11-26
    • 2021-08-20
    • 2021-11-01
    • 2022-10-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-12-10
    • 2021-10-07
    相关资源
    最近更新 更多