Flutter實現(xiàn)軟鍵盤與其它區(qū)域絲滑切換效果
效果演示

問題產生
本次要解決的問題是實現(xiàn)實現(xiàn)軟鍵盤和其它區(qū)域的絲滑切換,我們點擊微信的表情和鍵盤,不難發(fā)現(xiàn)輸入框可以一直保持穩(wěn)定,仿佛表情抽屜就藏在軟鍵盤后面。 我剛開始的解決思路是,當軟鍵盤收起展示表情抽屜,當表情抽屜收起后展示軟鍵盤,但很快就發(fā)現(xiàn)了問題,軟鍵盤與表情抽屜切換的過程中,會造成頁面的震蕩
問題分析
我錄視頻后慢倍速分析,發(fā)現(xiàn)原因是鍵盤收縮同時表情抽屜的container開始上升,但鍵盤收縮的距離不等于container上升的距離,導致輸入框不穩(wěn)定。 查閱資料后發(fā)現(xiàn)安卓的思路是獲取軟鍵盤高度,將輸入框控制在一個固定高度,但是Flutter各種組件的位置取決于與其它組件的位置關系,除非使用stack圖層,才能將輸入框設置為固定高度,但這樣做會給鍵盤收起步驟帶來困難,因此pass。
解決思路
其實解決方法就在問題分析中,不知道你發(fā)現(xiàn)了嗎
鍵盤收縮同時表情抽屜的container開始上升,但鍵盤收縮的距離不等于container上升的距離,導致輸入框不穩(wěn)定
那我們就讓鍵盤收縮距離等于container上升距離,不就可以保持輸入框的高度了嗎 我們以語音輸入區(qū)為例,重要步驟主要有兩步
- 獲取鍵盤的最大高度,即輸入框底部的距離,我們設置為InputHeight
- 獲取鍵盤的實時高度,使用InputHeight-currentKeyboardHeight,即可獲得voiceInputHeight的高度,使用Provider實時更新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; // 假設這是初始輸入框的高度
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();
}
// 獲取鍵盤的實時高度
@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;
// 設置一個新的計時器
_debounceTimer?.cancel(); // 取消之前的計時器
_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), // 使用最大值確保不會有負數的高度
),
],
),
);
}問題升級
我們再往深思考一下,這是軟鍵盤和其中某一個區(qū)域轉化的思路,如果再加區(qū)域2,那區(qū)域1、區(qū)域2和軟鍵盤直接切換,如何保持輸入框高度不變呢 在此我提供一個思路
- 在Provider中添加變量命名為Container1Show、Container2Show,為bool類型
- 點擊按鈕為bool值賦值,同時高度計算沿用上面的方法,只是這次輸入框距離底部高度最大值為這三部分的高度之和,而不僅僅是兩部分高度之和
以上就是Flutter實現(xiàn)軟鍵盤與其它區(qū)域絲滑切換效果的詳細內容,更多關于Flutter軟鍵盤切換的資料請關注腳本之家其它相關文章!
相關文章
Android實現(xiàn)微信朋友圈發(fā)本地視頻功能
這篇文章主要介紹了Android實現(xiàn)微信朋友圈發(fā)本地視頻功能的相關資料,非常不錯,具有參考借鑒價值,需要的朋友可以參考下2016-11-11
Android permission denied原因歸納和解決辦法
大家好,本篇文章主要講的是Android permission denied原因歸納和解決辦法,感興趣的同學趕快來看一看吧,對你有幫助的話記得收藏一下哦2021-12-12
Android 百度地圖marker中圖片不顯示的解決方法(推薦)
下面小編就為大家分享一篇Android 百度地圖marker中圖片不顯示的解決方法(推薦),具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2018-01-01
Android開發(fā)使用Drawable繪制圓角與圓形圖案功能示例
這篇文章主要介紹了Android開發(fā)使用Drawable繪制圓角與圓形圖案功能,結合具體實例形式分析了Drawable繪制圓角矩形的實現(xiàn)步驟與使用方法,需要的朋友可以參考下2017-10-10
View中如何進行手勢識別onFling動作實現(xiàn)介紹
下面我們就以實現(xiàn)手勢識別的onFling動作,在CwjView中我們從View類繼承,當然大家可以從TextView等更高層的界面中實現(xiàn)觸控,感興趣的朋友可以了解下哈2013-06-06

