国产睡熟迷奷白丝护士系列精品,中文色字幕网站,免费h网站在线观看的,亚洲开心激情在线

      <sup id="hb9fh"></sup>
          1. 千鋒教育-做有情懷、有良心、有品質(zhì)的職業(yè)教育機(jī)構(gòu)

            手機(jī)站
            千鋒教育

            千鋒學(xué)習(xí)站 | 隨時隨地免費(fèi)學(xué)

            千鋒教育

            掃一掃進(jìn)入千鋒手機(jī)站

            領(lǐng)取全套視頻
            千鋒教育

            關(guān)注千鋒學(xué)習(xí)站小程序
            隨時隨地免費(fèi)學(xué)習(xí)課程

            當(dāng)前位置:首頁  >  技術(shù)干貨  > Flutter鍵盤頂起底部

            Flutter鍵盤頂起底部

            來源:千鋒教育
            發(fā)布人:xqq
            時間: 2023-11-23 00:46:24 1700671584

            在Flutter中,打開鍵盤后,我們可能希望底部的內(nèi)容不被覆蓋。Flutter提供了一些方法來實(shí)現(xiàn)這一點(diǎn)。下面將從多個方面詳細(xì)闡述如何使用Flutter實(shí)現(xiàn)鍵盤頂起底部的效果。

            一、使用SingleChildScrollView

            使用SingleChildScrollView可以讓底部內(nèi)容在鍵盤彈出時自動滾動到可見區(qū)域。我們只需要將底部內(nèi)容包裹在SingleChildScrollView中,并在頁面初始化時獲得一個GlobalKey,然后在鍵盤彈出后通過該GlobalKey定位到bottom widget的位置,再通過動畫滾動到該位置。

            class MyWidget extends StatefulWidget {
              @override
              _MyWidgetState createState() => _MyWidgetState();
            }
            
            class _MyWidgetState extends State {
              final GlobalKey _bottomWidgetKey = GlobalKey();
            
              @override
              Widget build(BuildContext context) {
                return Scaffold(
                  body: SingleChildScrollView(
                    child: Column(
                      children: [
                        // other widgets
                        Container(
                          key: _bottomWidgetKey,
                          child: // bottom widget
                        ),
                      ],
                    ),
                  ),
                  appBar: AppBar(
                    title: Text("Keyboard"),
                  ),
                  floatingActionButton: FloatingActionButton(
                    onPressed: () {
                      // Show the keyboard
                      FocusScope.of(context).requestFocus(FocusNode());
                    },
                    child: Icon(Icons.add),
                  ),
                );
              }
            
              @override
              void initState() {
                super.initState();
                final BottomWidgetRenderBox =
                    _bottomWidgetKey.currentContext.findRenderObject() as RenderBox;
                SchedulerBinding.instance!.addPostFrameCallback((_) {
                  Future.delayed(const Duration(milliseconds: 300)).then((_) {
                    final RenderBox keyboard =
                        context.findRenderObject() as RenderBox;
                    final keyboardHeight = keyboard.size.height;
                    final heightDiff =
                        keyboardHeight - (MediaQuery.of(context).viewInsets.bottom);
                    final double offsetY =
                        heightDiff > 0 ? -(BottomWidgetRenderBox.size.height + heightDiff) : 0;
                    if (offsetY != 0) {
                      _controller.animateTo(
                          _controller.offset + offsetY,
                          duration: new Duration(milliseconds: 300),
                          curve: Curves.easeOut);
                    }
                  });
                });
              }
            }

            二、使用ListView

            如果你希望底部內(nèi)容可以滾動,我們可以使用ListView。ListView將自動在鍵盤彈出時滾動到底部,并且可以讓用戶滾動以查看所有內(nèi)容。

            class MyWidget extends StatelessWidget {
              @override
              Widget build(BuildContext context) {
                return Scaffold(
                  body: Column(
                    children: [
                      Expanded(
                        child: ListView(
                          children: [
                            // other widgets
                            // bottom widget
                          ],
                        ),
                      ),
                      // input widget
                    ],
                  ),
                  appBar: AppBar(
                    title: Text("ListView"),
                  ),
                );
              }
            }

            三、使用Stack和AnimatedPositioned

            使用Stack和AnimatedPositioned可以在鍵盤彈出時自動調(diào)整底部內(nèi)容的位置,使其不被鍵盤遮擋。我們可以將輸入框作為Stack的子元素,然后將底部內(nèi)容作為Stack的第二個子元素。在鍵盤彈出時,我們可以使用AnimatedPositioned調(diào)整第二個子元素的位置。

            class MyWidget extends StatefulWidget {
              @override
              _MyWidgetState createState() => _MyWidgetState();
            }
            
            class _MyWidgetState extends State {
              GlobalKey _globalKey = GlobalKey();
            
              double _bottom = 0;
            
              @override
              Widget build(BuildContext context) {
                return Scaffold(
                  resizeToAvoidBottomInset: false,
                  appBar: AppBar(
                    title: Text("Stack and AnimatedPositioned"),
                  ),
                  body: Stack(
                    children: [
                      Positioned(
                        top: 0,
                        bottom: 0,
                        left: 0,
                        right: 0,
                        child: GestureDetector(
                          onTap: () => FocusScope.of(context).requestFocus(FocusNode()),
                          child: Container(
                            color: Colors.white,
                            child: SingleChildScrollView(
                              child: Column(
                                key: _globalKey,
                                children: [
                                  // other widgets
                                  Container(
                                    height: 800,
                                  ),
                                ],
                              ),
                            ),
                          ),
                        ),
                      ),
                      AnimatedPositioned(
                        duration: Duration(milliseconds: 300),
                        bottom: _bottom,
                        left: 0,
                        right: 0,
                        child: Container(
                          color: Colors.lightBlue,
                          height: 140,
                          child: Center(
                            child: GestureDetector(
                              onTap: () {
                                FocusScope.of(context).requestFocus(FocusNode());
                              },
                              child: Text(
                                "Input",
                                style: TextStyle(
                                  fontSize: 30,
                                  color: Colors.white,
                                ),
                              ),
                            ),
                          ),
                        ),
                      ),
                    ],
                  ),
                );
              }
            
              @override
              void initState() {
                super.initState();
                final RenderBox renderBoxRed = _globalKey.currentContext.findRenderObject() as RenderBox;
                WidgetsBinding.instance!.addPostFrameCallback((_) {
                  double height = renderBoxRed.size.height;
                  double screenHeight = MediaQuery.of(context).size.height;
                  double diff = screenHeight - height;
                  setState(() {
                    _bottom = diff;
                  });
                });
              }
            }

            四、結(jié)合SingleChildScrollView和Stack

            我們也可以結(jié)合ScrollView和Stack來實(shí)現(xiàn)鍵盤頂起底部的效果。具體操作是將輸入框與底部內(nèi)容放置在Stack中,并將Stack放置在SingleChildScrollView中。當(dāng)鍵盤彈出時,可以與第一種方法類似地通過AnimationController將底部內(nèi)容滑動到屏幕中央。

            class MyWidget extends StatefulWidget {
              @override
              _MyWidgetState createState() => _MyWidgetState();
            }
            
            class _MyWidgetState extends State
                with SingleTickerProviderStateMixin {
              double _offset = 0.0;
            
              bool _isKeyboardShowing = false;
            
              late final AnimationController _controller = AnimationController(
                  duration: const Duration(milliseconds: 200), vsync: this);
            
              @override
              Widget build(BuildContext context) {
                return Scaffold(
                  resizeToAvoidBottomInset: false,
                  appBar: AppBar(
                    title: Text("Stack and SingleChildScrollView"),
                  ),
                  body: SingleChildScrollView(
                    child: Stack(
                      children: [
                        Column(
                          children: [
                            Container(
                              height: 800,
                            ),
                          ],
                        ),
                        Positioned(
                          bottom: _offset,
                          left: 0,
                          right: 0,
                          child: Container(
                            color: Colors.lightBlue,
                            height: 140,
                            child: Center(
                              child: GestureDetector(
                                onTap: () {
                                  FocusScope.of(context).requestFocus(FocusNode());
                                },
                                child: Text(
                                  "Input",
                                  style: TextStyle(
                                    fontSize: 30,
                                    color: Colors.white,
                                  ),
                                ),
                              ),
                            ),
                          ),
                        ),
                      ],
                    ),
                  ),
                );
              }
            
              @override
              void initState() {
                super.initState();
                _controller.addListener(() {
                  setState(() {
                    _offset =
                        MediaQuery.of(context).viewInsets.bottom * _controller.value;
                  });
                });
                _controller.addStatusListener((status) {
                  if (status == AnimationStatus.completed) {
                    setState(() {
                      _isKeyboardShowing = true;
                    });
                  } else if (status == AnimationStatus.dismissed) {
                    setState(() {
                      _isKeyboardShowing = false;
                    });
                  }
                });
              }
            
              @override
              void dispose() {
                _controller.dispose();
                super.dispose();
              }
            
              @override
              Widget build(BuildContext context) {
                return Scaffold(
                  resizeToAvoidBottomInset: false,
                  appBar: AppBar(
                    title: Text("Stack and SingleChildScrollView"),
                  ),
                  body: SingleChildScrollView(
                    child: Stack(
                      children: [
                        Column(
                          children: [
                            Container(
                              height: 800,
                            ),
                            GestureDetector(
                              onTap: () {
                                FocusScope.of(context).requestFocus(FocusNode());
                              }
                              child: // input widget
                            ),
                          ],
                        ),
                        Positioned(
                          bottom: _offset,
                          left: 0,
                          right: 0,
                          child: Container(
                            color: Colors.lightBlue,
                            height: 140,
                            child: Center(
                              child: GestureDetector(
                                onTap: () {
                                  FocusScope.of(context).requestFocus(FocusNode());
                                },
                                child: Text(
                                  "Input",
                                  style: TextStyle(
                                    fontSize: 30,
                                    color: Colors.white,
                                  ),
                                ),
                              ),
                            ),
                          ),
                        )
                      ],
                    ),
                  ),
                );
              }
            
              void _handleFocusChange() {
                if (FocusScope.of(context).hasFocus != _isKeyboardShowing) {
                  _isKeyboardShowing = FocusScope.of(context).hasFocus;
                  _controller.animateTo(
                      _isKeyboardShowing ? 1.0 : 0.0,
                      duration: const Duration(milliseconds: 150),
                      curve: Curves.linear);
                }
              }
            }

            五、小結(jié)

            本文介紹了Flutter中實(shí)現(xiàn)鍵盤頂起底部的幾種方法,包括使用SingleChildScrollView、ListView、Stack以及結(jié)合方法。在使用這些方法時,我們需要考慮底部內(nèi)容的特殊結(jié)構(gòu),確保鍵盤彈出時,底部內(nèi)容不會被遮擋。希望本文能對您在Flutter開發(fā)中實(shí)現(xiàn)鍵盤頂起底部的需求提供幫助。

            聲明:本站稿件版權(quán)均屬千鋒教育所有,未經(jīng)許可不得擅自轉(zhuǎn)載。
            10年以上業(yè)內(nèi)強(qiáng)師集結(jié),手把手帶你蛻變精英
            請您保持通訊暢通,專屬學(xué)習(xí)老師24小時內(nèi)將與您1V1溝通
            免費(fèi)領(lǐng)取
            今日已有369人領(lǐng)取成功
            劉同學(xué) 138****2860 剛剛成功領(lǐng)取
            王同學(xué) 131****2015 剛剛成功領(lǐng)取
            張同學(xué) 133****4652 剛剛成功領(lǐng)取
            李同學(xué) 135****8607 剛剛成功領(lǐng)取
            楊同學(xué) 132****5667 剛剛成功領(lǐng)取
            岳同學(xué) 134****6652 剛剛成功領(lǐng)取
            梁同學(xué) 157****2950 剛剛成功領(lǐng)取
            劉同學(xué) 189****1015 剛剛成功領(lǐng)取
            張同學(xué) 155****4678 剛剛成功領(lǐng)取
            鄒同學(xué) 139****2907 剛剛成功領(lǐng)取
            董同學(xué) 138****2867 剛剛成功領(lǐng)取
            周同學(xué) 136****3602 剛剛成功領(lǐng)取
            相關(guān)推薦HOT