Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

There is a problem that is rebuild when I click TextField() in Flutter

My code includes FutureBuilder(), which get data from Firestore, and its child widgets include GridView.builder and TextField widgets etc.

When I click on a TexField(focus), the codes in FutureBuilder are rebuild.

The following is the test code for this.

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

Can you tell me the cause and solution of this problem?

class TestRoom extends StatefulWidget {
  TestRoom({Key? key}) : super(key: key);

  @override
  State<TestRoom> createState() => _TestRoomState();
}

class _TestRoomState extends State<TestRoom> {
  List<RoomModel> _roomModels = [];
  TextEditingController _textEditingController = TextEditingController();
  bool _isTablet = false;

  @override
  void dispose() {
    _textEditingController.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    Size size = MediaQuery.of(context).size;

    if (size.width >= 800) {
      _isTablet = true;
    } else {
      _isTablet = false;
    }

    return Scaffold(
      appBar: AppBar(),
      body: Padding(
        padding: EdgeInsets.all(20),
        child: Column(
          crossAxisAlignment: CrossAxisAlignment.start,
          children: [
            const Text(
              "Test",
              style: TextStyle(
                fontSize: 35,
                fontWeight: FontWeight.bold,
              ),
            ),
            SizedBox(
              height: 20,
            ),
            FutureBuilder(
              future: _getAllRoom(),
              builder: (context, snapshot) {
                if (snapshot.connectionState == ConnectionState.waiting) {
                  return const Center(
                    child: CircularProgressIndicator(),
                  );
                }

                return Expanded(
                    child: TestList1(
                  isTablet: _isTablet,
                  roomModels: _roomModels,
                  isListStyle1: true,
                ));
              },
            ),
          ],
        ),
      ),
    );
  }

  // get user's models from firestore
  Future _getAllRoom() async {
    _roomModels.clear();
    _roomModels.addAll(await RoomService().getAllRoomModel("userName"));
  }
}

//
//

class TestList1 extends StatefulWidget {
  final isTablet;
  final List<RoomModel> roomModels;
  final bool isListStyle1;

  TestList1({
    Key? key,
    required this.isTablet,
    required this.roomModels,
    required this.isListStyle1,
  }) : super(key: key);

  @override
  State<TestList1> createState() => _TestList1State();
}

class _TestList1State extends State<TestList1> {
  TextEditingController _textEditingController = TextEditingController();
  double _paddingSize = 40.0;

  @override
  void dispose() {
    // _textEditingController.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return GridView.builder(
      shrinkWrap: true,
      gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
        crossAxisCount: widget.isTablet ? 6 : 3,
        childAspectRatio: 1 / 1.5,
        mainAxisSpacing: _paddingSize,
        crossAxisSpacing: 10,
      ),
      itemBuilder: (context, index) {
        return _buildMyRooms(widget.roomModels[index], index);
      },
      itemCount: widget.roomModels.length,
    );
  }

  Widget _buildMyRooms(RoomModel roomModel, int index) {
    return Column(
      children: [
        InkWell(
          onTap: () {},
          child: Container(
            width: 120,
            height: 168,
            decoration: BoxDecoration(
              color: Colors.white,
              border: Border.all(
                color: Colors.blue,
                width: 2.0,
              ),
              borderRadius: const BorderRadius.all(
                Radius.circular(10),
              ),
            ),
          ),
        ),
        SizedBox(
          height: sm_padding,
        ),
        PopupMenuButton<int>(
          color: Colors.grey[100],
          itemBuilder: (context) => _fileMenuItemLust(roomModel),
          onSelected: _onSeletedFileMenu,
          child: Column(
            children: [
              Container(
                width: 130,
                child: Row(
                  mainAxisAlignment: MainAxisAlignment.center,
                  children: [
                    Flexible(
                      child: Text(
                        roomModel.roomName,
                        overflow: TextOverflow.ellipsis,
                        maxLines: 1,
                        style: const TextStyle(
                          color: Colors.blue,
                          fontSize: 15,
                        ),
                      ),
                    ),
                    const Icon(
                      Icons.arrow_drop_down_outlined,
                      color: Colors.blue,
                    ),
                  ],
                ),
              ),
            ],
          ),
        )
      ],
    );
  }

  // 파일 메뉴 아이템
  List<PopupMenuEntry<int>> _fileMenuItemLust(RoomModel roomModel) {
    _textEditingController.text = roomModel.roomName;

    return [
      // 파일명
      PopupMenuItem(
        enabled: false,
        // TODO textfield
        child: TextField(
            controller: _textEditingController,
            style: const TextStyle(
              color: Colors.white,
              fontWeight: FontWeight.bold,
            ),
            maxLines: 1,
            decoration: InputDecoration(
              border: _textFieldBorder(),
              enabledBorder: _textFieldBorder(),
              disabledBorder: _textFieldBorder(),
              focusedBorder: _textFieldBorder(),
              focusColor: Colors.white60,
              filled: true,
              fillColor: Colors.grey.withOpacity(0.3),
              isDense: true, // padding 조절을 위해 추가
              contentPadding: EdgeInsets.all(sm_padding),
            )),
      ),
      const PopupMenuDivider(),
      PopupMenuItem(
        value: 0,
        child: Row(
          children: [
            const Icon(
              Icons.copy,
            ),
            SizedBox(
              width: sm_padding,
            ),
            const Text(
              "Menu Item1",
            ),
          ],
        ),
      ),
    ];
  }

  void _onSeletedFileMenu(value) {}

  OutlineInputBorder _textFieldBorder() {
    return OutlineInputBorder(
      borderRadius: BorderRadius.all(Radius.circular(20)),
      borderSide: BorderSide(
        color: Colors.grey.withOpacity(0.3),
        width: 1,
      ),
    );
  }
}

>Solution :

Here future: _getAllRoom() calls the api on every state changes.

Create a state variable for future

  late final myFuture  =  _getAllRoom();
  @override
  Widget build(BuildContext context) {

And use

FutureBuilder(
  future:myFuture  ,

You can check Fixing a common FutureBuilder and StreamBuilder problem

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading