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ì)造成頁面的震蕩
問題分析
我錄視頻后慢倍速分析,發(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ú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-07
Android 控制ScrollView滾動(dòng)的實(shí)例詳解
這篇文章主要介紹了Android 控制ScrollView滾動(dòng)的實(shí)例詳解的相關(guān)資料,希望通過本文能幫助到大家,需要的朋友可以參考下2017-10-10
Android實(shí)現(xiàn)微信朋友圈發(fā)本地視頻功能
這篇文章主要介紹了Android實(shí)現(xiàn)微信朋友圈發(fā)本地視頻功能的相關(guān)資料,非常不錯(cuò),具有參考借鑒價(jià)值,需要的朋友可以參考下2016-11-11
Android 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-02
Android 百度地圖marker中圖片不顯示的解決方法(推薦)
下面小編就為大家分享一篇Android 百度地圖marker中圖片不顯示的解決方法(推薦),具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧2018-01-01
Android開發(fā)使用Drawable繪制圓角與圓形圖案功能示例
這篇文章主要介紹了Android開發(fā)使用Drawable繪制圓角與圓形圖案功能,結(jié)合具體實(shí)例形式分析了Drawable繪制圓角矩形的實(shí)現(xiàn)步驟與使用方法,需要的朋友可以參考下2017-10-10
View中如何進(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

