Vintage appMaker의 Tech Blog

[Flutter] keyboard 위에 TextField 노출시키기 본문

Source code or Tip/Flutter & Dart

[Flutter] keyboard 위에 TextField 노출시키기

VintageappMaker 2022. 6. 8. 10:37

 

 

 

iOS와 Android 모두에서 은근 스트레스 받는 것이 

 

키보드 노출시 Edit 화면이 사라지는 현상이다.

 

 

그런 현상을 없애기 위해 iOS와 Android에서는 수많은 예제코드들이 공유되고 있지만 상황에 따라 완벽하지 않게 돌아가는 경우도 많다. 

 

Flutter에서도 키보드 화면이 보여질 시, Edit 화면을 위로 올리는 방법이 존재한다. 

크게 2가지 상황에서 처리가 되는 데

 

1. 일반화면에서 처리
2. modalSheet화면에서 처리


가 있다.

 

일반화면에서는 간단하게 처리가 가능하다. 최상위를 SingleChildScrollView로 감사고 Scaffold의 속성을 

resizeToAvoidBottomInset: true으로 하면 된다.

 

그리고 modal화면의 경우는 

showModalBottomSheet를 호출시 
-> isScrollControlled: true
-> bottom: MediaQuery.of(context).viewInsets.bottom
를 설정하면 된다.

 

다음은 간단한 소스이다.

 

[전체소스 ]

import 'package:flutter/material.dart';

void main() {
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({Key? key}) : super(key: key);

  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: const MyHomePage(title: 'Flutter Demo Home Page'),
    );
  }
}

class MyHomePage extends StatefulWidget {
  const MyHomePage({Key? key, required this.title}) : super(key: key);

  final String title;

  @override
  State<MyHomePage> createState() => _MyHomePageState();
}


class _MyHomePageState extends State<MyHomePage> {

  void showMenu() {
    final TextEditingController _titleController = TextEditingController();
    final TextEditingController _descriptionController = TextEditingController();

    // 키보드 입력시, TextEdit를 상단으로 움직임.
    // isScrollControlled: true
    // bottom: MediaQuery.of(context).viewInsets.bottom
    showModalBottomSheet(
        isScrollControlled: true,
        context: context,
        builder: (context) =>
            Container(
                padding: EdgeInsets.only(
                  bottom: MediaQuery
                      .of(context)
                      .viewInsets
                      .bottom,
                ),
                child: Padding(
                  padding: const EdgeInsets.all(18.0),
                  child: Column(
                    mainAxisSize: MainAxisSize.min,
                    crossAxisAlignment: CrossAxisAlignment.end,
                    children: [
                      TextField(
                        controller: _titleController,
                        decoration: const InputDecoration(hintText: 'Title'),
                      ),
                      const SizedBox(
                        height: 10,
                      ),
                      TextField(
                        controller: _descriptionController,
                        decoration: const InputDecoration(
                            hintText: 'Description'),
                      ),
                      const SizedBox(
                        height: 20,
                      ),
                      ElevatedButton(
                          onPressed: () async {
                            Navigator.of(context).pop();
                          },
                          child: Text(
                              'Create New') //Text(id == null ? 'Create New' : 'Update'),
                      )
                    ],
                  ),
                )),
        enableDrag: true
    );
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(widget.title),
      ),
      resizeToAvoidBottomInset: true,
      body: SingleChildScrollView(
      child: Container(
        child: Column(
          children: <Widget>[
            SizedBox(height: MediaQuery.of(context).size.height - 200,),
            TextFormField(
              decoration: InputDecoration(
                hintText: '#1 입력하세요',
              ),
            ),
          ],
        ),
      ),
    ),
      floatingActionButton: FloatingActionButton(
        onPressed: showMenu,
        tooltip: 'showModalSheet',
        child: const Icon(Icons.add),
      ),
    );
  }
}
Comments