Android 全局监听软键盘弹起隐藏 动态修改布局并适配无限循环的问题

思路:

要在 Android 应用中全局检测软键盘的弹起,您可以使用 ViewTreeObserver.OnGlobalLayoutListener 监听器来监听布局树的变化。当软键盘弹起或隐藏时,布局树会发生变化,因此您可以在监听器中捕获这些变化。

以下是一个示例,展示如何在全局范围内检测软键盘的弹起:

复制代码
import android.graphics.Rect;
import android.os.Bundle;
import android.view.View;
import android.view.ViewTreeObserver;
import androidx.appcompat.app.AppCompatActivity;

public class MainActivity extends AppCompatActivity {

    private View rootView;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        rootView = findViewById(R.id.rootView); // Replace with your root layout's ID

        // Register a global layout listener
        rootView.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
            @Override
            public void onGlobalLayout() {
                // Get the height of the visible display area
                Rect rect = new Rect();
                rootView.getWindowVisibleDisplayFrame(rect);
                int screenHeight = rootView.getHeight();
                int keyboardHeight = screenHeight - rect.bottom;

                // If the keyboard height is greater than a threshold (e.g., 100 pixels), the keyboard is likely visible
                if (keyboardHeight > 100) {
                    // Keyboard is visible, do something
                } else {
                    // Keyboard is hidden, do something else
                }
            }
        });
    }
}

在上面的代码中,rootView 是您布局的根视图,您需要将其替换为您实际布局的根视图。addOnGlobalLayoutListener 方法用于注册一个监听器,当布局树发生变化时会调用 onGlobalLayout 方法。

onGlobalLayout 方法中,您可以通过比较屏幕高度和可见区域的底部位置来计算软键盘的高度。根据计算结果,您可以判断软键盘是否可见,并执行相应的操作。

以下是一个在项目中的实际示例,解决无限循环的示例:

复制代码
private void changerBottomView() {
        binding.includedNoteMenu.fragmentLl.getViewTreeObserver().addOnGlobalLayoutListener(onGlobalLayoutListener);
}
    

private ViewTreeObserver.OnGlobalLayoutListener onGlobalLayoutListener = new ViewTreeObserver.OnGlobalLayoutListener() {
        @Override
        public void onGlobalLayout() {
            Rect rect = new Rect();
            //取得 rootView 可视区域
            binding.includedNoteMenu.fragmentLl.getWindowVisibleDisplayFrame(rect);
            //取得 rootView 不可视区域高度 (被其他View遮挡的区域高度)
            int rootInvisibleHeight = binding.includedNoteMenu.fragmentLl.getRootView().getHeight() - rect.bottom;
            LogUtil.i("shawn","rootInvisibleHeight = " + rootInvisibleHeight);
            ViewGroup.MarginLayoutParams layoutParams = (ViewGroup.MarginLayoutParams)binding.includedNoteMenu.fragmentLl.getLayoutParams();
            if (layoutParams.bottomMargin != rootInvisibleHeight + UiUtil.dp2px(10)) {
                layoutParams.bottomMargin = rootInvisibleHeight + UiUtil.dp2px(10);
                binding.includedNoteMenu.fragmentLl.setLayoutParams(layoutParams);
            }

        }
    };

日志: 只会多调用一次,在第二次回调时,条件已不满足,不会再调用setLayoutParams

复制代码
I/shawn: [ main: AddNoteFragment.java:173 onGlobalLayout ] - rootInvisibleHeight = 840
I/shawn: [ main: AddNoteFragment.java:173 onGlobalLayout ] - rootInvisibleHeight = 840
I/shawn: [ main: AddNoteFragment.java:173 onGlobalLayout ] - rootInvisibleHeight = -4
I/shawn: [ main: AddNoteFragment.java:173 onGlobalLayout ] - rootInvisibleHeight = -4
相关推荐
liux35288 分钟前
MySQL执行计划与索引优化全面解析(三)
android·mysql·adb
上天_去_做颗惺星 EVE_BLUE1 小时前
Android设备与Mac/Docker全连接指南:有线到无线的完整方案
android·linux·macos·adb·docker·容器·安卓
zhangphil1 小时前
Android显示系统性能分析:trace的HWUI All Memory与HWUI Misc Memory
android
2501_916008891 小时前
iOS开发APP上架全流程解析:从开发到App Store的完整指南
android·ios·小程序·https·uni-app·iphone·webview
冬奇Lab1 小时前
【Kotlin系列08】泛型进阶:从型变到具体化类型参数的类型安全之旅
android·开发语言·windows·安全·kotlin
摘星编程2 小时前
React Native for OpenHarmony 实战:HorizontalScroll 横向滚动详解
android·react native·react.js
行稳方能走远2 小时前
Android C++ 学习笔记5
android·c++
shughui2 小时前
Android SDK 下载、安装与配置(详细图文附安装包,适配Appium+Python自动化)
android·python·appium·android-studio·android sdk
SHEN_ZIYUAN11 小时前
深度解析:从 AnimationHandler 原理看 Android 动画内存泄漏
android
冬奇Lab12 小时前
稳定性性能系列之十六——车机特定场景:黑卡死问题分析与排查实战
android·性能优化