【问题标题】:Why does my widget rebuild when I use keyboard为什么当我使用键盘时我的小部件会重建
【发布时间】:2021-07-04 12:07:46
【问题描述】:

当键盘出现时,我遇到了重建小部件的问题。我尝试使用 sizer 包,但永远无法弄清楚如何让它工作 当我从这个屏幕返回时,前一个屏幕中的所有内容都将重建,请注意:如果我不点击typeaheadwidget,这样键盘就不会出现,状态会保留在前一个屏幕中,但只要键盘弹出小部件得到重建 你能查一下吗?

class SearchScreen extends StatefulWidget {
  @override
  _SearchScreenState createState() => _SearchScreenState();
}

class _SearchScreenState extends State<SearchScreen> {
  TextEditingController pickUpTextEditingController = TextEditingController();
  TextEditingController dropOffTextEditingController = TextEditingController();

  @override
  void initState() {
    super.initState();
  }

  @override
  @mustCallSuper
  Widget build(BuildContext context) {
    String placeAddress =
        Provider.of<AppData>(context).pickUpLocation.placeName ?? "";
    pickUpTextEditingController.text = placeAddress;

    return Scaffold(
      resizeToAvoidBottomInset: false,
      body: Stack(
        children: [
          Container(
            height: 250.0,
            decoration: BoxDecoration(
              color: Colors.white,
              boxShadow: [
                BoxShadow(
                  color: Colors.black,
                  blurRadius: 6.0,
                  spreadRadius: 0.5,
                  offset: Offset(0.7, 0.7),
                )
              ],
            ),
            child: Padding(
              padding: EdgeInsets.only(
                  left: 25.0, top: 30.0, right: 25.0, bottom: 20.0),
              child: Column(
                children: [
                  SizedBox(height: 5.0),
                  Stack(
                    children: [
                      GestureDetector(
                          onTap: () {
                            Navigator.pop(
                                //send back data
                                context,
                                dropOffTextEditingController.text);
                          },
                          child: Icon(Icons.arrow_back)),
                      Center(
                        child: Text(
                          "Set Drop Off",
                          style: TextStyle(
                              fontSize: 18.0, fontFamily: "Brand-Bold"),
                        ),
                      )
                    ],
                  ),
                  SizedBox(height: 16.0),
                  Row(
                    children: [
                      Image.asset("images/images/pickicon.png",
                          height: 16.0, width: 16.0),
                      SizedBox(width: 18.0),
                      Expanded(
                          child: Container(
                        decoration: BoxDecoration(
                          color: Colors.grey[400],
                          borderRadius: BorderRadius.circular(5.0),
                        ),
                        child: Padding(
                          padding: EdgeInsets.all(3.0),
                          child: TextField(
                            controller: pickUpTextEditingController,
                            decoration: InputDecoration(
                              hintText: "PickUp Location",
                              fillColor: Colors.grey[400],
                              filled: true,
                              border: InputBorder.none,
                              isDense: true,
                              contentPadding: EdgeInsets.only(
                                  left: 11.0, top: 8.0, bottom: 8.0),
                            ),
                          ),
                        ),
                      ))
                    ],
                  ),
                  SizedBox(height: 10.0),
                  Row(
                    children: [
                      Image.asset("images/images/desticon.png",
                          height: 16.0, width: 16.0),
                      SizedBox(width: 18.0),
                      Expanded(
                        child: Container(
                          decoration: BoxDecoration(
                            color: Colors.grey[400],
                            borderRadius: BorderRadius.circular(5.0),
                          ),
                          child: Padding(
                            padding: EdgeInsets.all(3.0),
                            child: TypeAheadField(
                              itemBuilder: null,
                              onSuggestionSelected: null,
                              suggestionsCallback: null,
                            ),
                          ),
                        ),
                      ),
                    ],
                  ),
                ],
              ),
            ),
          ),
        ],
      ),
    );
  }
}

【问题讨论】:

    标签: flutter dart


    【解决方案1】:

    您不应该尝试控制何时调用build 方法。 Flutter 会在需要时调用build(例如,键盘出现、设备旋转、父级重建等)。

    相反,您应该确保您的构建方法是“纯”函数。特别是在 Flutter 中,这意味着您不应该执行任何带有“副作用”的操作(基本上是任何修改应用程序状态的操作)。

    例如:

    Widget build(BuildContext context) {
      final x = 2 + 3;  // fine, nothing else is modified
      final state = context.watch<MyModel>();  // also fine, only reading data
      controller.text = "hello";  // BAD, modifies the state of the app
    
      return ...;
    }
    

    相反,您应该将具有副作用的逻辑移至其他生命周期方法(例如initState()didChangeDepencencies() 等)。

    例如,如果您想在文本字段首次出现时将其设置为特定字符串,您可以使用initState

    class _SearchScreenState extends State<SearchScreen> {
      @override
      void initState() {
        super.initState();
        final data = context.read<AppData>();
        controller.text = data.pickUpLocation.placeName ?? "";
      }
    
      Widget build(BuildContext context) {
        // ...
      }
    }
    

    现在可以随时调用build(),而无需重置文本字段的状态。

    请注意,即使有某种方法可以防止您的小部件被重建,这也可能不是您想要的,因为 UI 不会更新以适应键盘。

    【讨论】:

    • 虽然我仍然遇到问题,但感谢您为我指明了正确的方向。我会接受答案,因为这将帮助我解决它。
    【解决方案2】:

    当您点击TextField 小部件时,它会显示键盘。当键盘出现时,您的屏幕尺寸会发生变化。这会导致重建

    【讨论】:

    • 是的,先生!我明白我该如何解决它?
    • 嗨 Pannam ..你找到解决方案了吗?
    猜你喜欢
    • 2021-01-24
    • 2019-10-12
    • 1970-01-01
    • 1970-01-01
    • 2021-07-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多