欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

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

 更新時(shí)間:2024年03月10日 09:06:46   作者:yulittlemoon  
這篇文章主要為大家詳細(xì)介紹了如何使用Flutter實(shí)現(xiàn)軟鍵盤與其它區(qū)域絲滑切換效果,文中的示例代碼講解詳細(xì),需要的小伙伴可以跟隨小編一起學(xué)習(xí)一下

效果演示

問題產(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)文章

最新評(píng)論