Flutter實(shí)現(xiàn)軟鍵盤與其它區(qū)域絲滑切換效果
效果演示
問題產(chǎn)生
本次要解決的問題是實(shí)現(xiàn)實(shí)現(xiàn)軟鍵盤和其它區(qū)域的絲滑切換,我們點(diǎn)擊微信的表情和鍵盤,不難發(fā)現(xiàn)輸入框可以一直保持穩(wěn)定,仿佛表情抽屜就藏在軟鍵盤后面。 我剛開始的解決思路是,當(dāng)軟鍵盤收起展示表情抽屜,當(dāng)表情抽屜收起后展示軟鍵盤,但很快就發(fā)現(xiàn)了問題,軟鍵盤與表情抽屜切換的過程中,會(huì)造成頁(yè)面的震蕩
問題分析
我錄視頻后慢倍速分析,發(fā)現(xiàn)原因是鍵盤收縮同時(shí)表情抽屜的container開始上升,但鍵盤收縮的距離不等于container上升的距離,導(dǎo)致輸入框不穩(wěn)定。 查閱資料后發(fā)現(xiàn)安卓的思路是獲取軟鍵盤高度,將輸入框控制在一個(gè)固定高度,但是Flutter各種組件的位置取決于與其它組件的位置關(guān)系,除非使用stack圖層,才能將輸入框設(shè)置為固定高度,但這樣做會(huì)給鍵盤收起步驟帶來困難,因此pass。
解決思路
其實(shí)解決方法就在問題分析中,不知道你發(fā)現(xiàn)了嗎
鍵盤收縮同時(shí)表情抽屜的container開始上升,但鍵盤收縮的距離不等于container上升的距離,導(dǎo)致輸入框不穩(wěn)定
那我們就讓鍵盤收縮距離等于container上升距離,不就可以保持輸入框的高度了嗎 我們以語(yǔ)音輸入?yún)^(qū)為例,重要步驟主要有兩步
- 獲取鍵盤的最大高度,即輸入框底部的距離,我們?cè)O(shè)置為InputHeight
- 獲取鍵盤的實(shí)時(shí)高度,使用InputHeight-currentKeyboardHeight,即可獲得voiceInputHeight的高度,使用Provider實(shí)時(shí)更新container的高度
provider代碼如下
import 'package:flutter/material.dart'; class ProviderChatContent with ChangeNotifier { double _voiceInputHeight = 0.0; double get voiceInputHeight => _voiceInputHeight; void update_voiceInputHeight(double newHeight) { _voiceInputHeight = newHeight; notifyListeners(); } }
組件代碼如下
import 'dart:async'; import 'dart:math'; import 'package:flutter/material.dart'; import 'package:provider/provider.dart'; class YourClassName extends StatefulWidget { @override _YourClassNameState createState() => _YourClassNameState(); } class _YourClassNameState extends State<YourClassName> with WidgetsBindingObserver { Timer? _debounceTimer; final FocusNode _focusNode = FocusNode(); double ContainerHeight = 0.0; double InputHeight = 0.0; // 假設(shè)這是初始輸入框的高度 double voiceInputHeight = 0.0; @override void initState() { super.initState(); WidgetsBinding.instance.addObserver(this); } @override void dispose() { WidgetsBinding.instance.removeObserver(this); _debounceTimer?.cancel(); _focusNode.dispose(); super.dispose(); } // 獲取鍵盤的實(shí)時(shí)高度 @override void didChangeMetrics() { super.didChangeMetrics(); if (mounted) { final provider = Provider.of<ProviderChatContent>(context, listen: false); final double currentKeyboardHeight = EdgeInsets.fromWindowPadding( WidgetsBinding.instance.window.viewInsets, WidgetsBinding.instance.window.devicePixelRatio, ).bottom; // 設(shè)置一個(gè)新的計(jì)時(shí)器 _debounceTimer?.cancel(); // 取消之前的計(jì)時(shí)器 _debounceTimer = Timer(const Duration(milliseconds: 39), () { if (currentKeyboardHeight > 0 && _focusNode.hasFocus) { setState(() { // 更新 ContainerHeight 為 InputHeight 和 currentKeyboardHeight 的最大值 ContainerHeight = max(InputHeight, currentKeyboardHeight); }); } }); voiceInputHeight = InputHeight - currentKeyboardHeight; provider.update_voiceInputHeight(voiceInputHeight); } } @override Widget build(BuildContext context) { final provider = Provider.of<ProviderChatContent>(context); return Scaffold( body: Column( children: [ Row( // 此處填寫輸入框和其它代碼 ), Container( // 此處寫你的container height: max(provider.voiceInputHeight, 0.0), // 使用最大值確保不會(huì)有負(fù)數(shù)的高度 ), ], ), ); }
問題升級(jí)
我們?cè)偻钏伎家幌?,這是軟鍵盤和其中某一個(gè)區(qū)域轉(zhuǎn)化的思路,如果再加區(qū)域2,那區(qū)域1、區(qū)域2和軟鍵盤直接切換,如何保持輸入框高度不變呢 在此我提供一個(gè)思路
- 在Provider中添加變量命名為Container1Show、Container2Show,為bool類型
- 點(diǎn)擊按鈕為bool值賦值,同時(shí)高度計(jì)算沿用上面的方法,只是這次輸入框距離底部高度最大值為這三部分的高度之和,而不僅僅是兩部分高度之和
以上就是Flutter實(shí)現(xiàn)軟鍵盤與其它區(qū)域絲滑切換效果的詳細(xì)內(nèi)容,更多關(guān)于Flutter軟鍵盤切換的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
Android7.0 MTK設(shè)置默認(rèn)桌面
這篇文章主要為大家詳細(xì)介紹了Android7.0 MTK設(shè)置默認(rèn)桌面,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2019-07-07Android 控制ScrollView滾動(dòng)的實(shí)例詳解
這篇文章主要介紹了Android 控制ScrollView滾動(dòng)的實(shí)例詳解的相關(guān)資料,希望通過本文能幫助到大家,需要的朋友可以參考下2017-10-10Android實(shí)現(xiàn)微信朋友圈發(fā)本地視頻功能
這篇文章主要介紹了Android實(shí)現(xiàn)微信朋友圈發(fā)本地視頻功能的相關(guān)資料,非常不錯(cuò),具有參考借鑒價(jià)值,需要的朋友可以參考下2016-11-11Android permission denied原因歸納和解決辦法
大家好,本篇文章主要講的是Android permission denied原因歸納和解決辦法,感興趣的同學(xué)趕快來看一看吧,對(duì)你有幫助的話記得收藏一下哦2021-12-12詳解Android中的MVP架構(gòu)分解和實(shí)現(xiàn)
本篇文章主要介紹了詳解Android中的MVP架構(gòu)分解和實(shí)現(xiàn),小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2017-02-02Android 百度地圖marker中圖片不顯示的解決方法(推薦)
下面小編就為大家分享一篇Android 百度地圖marker中圖片不顯示的解決方法(推薦),具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧2018-01-01Android開發(fā)使用Drawable繪制圓角與圓形圖案功能示例
這篇文章主要介紹了Android開發(fā)使用Drawable繪制圓角與圓形圖案功能,結(jié)合具體實(shí)例形式分析了Drawable繪制圓角矩形的實(shí)現(xiàn)步驟與使用方法,需要的朋友可以參考下2017-10-10View中如何進(jìn)行手勢(shì)識(shí)別onFling動(dòng)作實(shí)現(xiàn)介紹
下面我們就以實(shí)現(xiàn)手勢(shì)識(shí)別的onFling動(dòng)作,在CwjView中我們從View類繼承,當(dāng)然大家可以從TextView等更高層的界面中實(shí)現(xiàn)觸控,感興趣的朋友可以了解下哈2013-06-06