android 软键盘在全屏下的布局计算问题

在非全屏模式下,将activity的windowSoftInputMode的属性设置为:adjustResize。同时在View的onSizeChanged(int w, int h, int oldw, int oldh)里可以得到变化后的尺寸,然后根据前后变化的结果来计算屏幕需要移动的距离。

但是在全屏模式下,即使将activity的windowSoftInputMode的属性设置为:adjustResize。在键盘显示时它未将Activity的Screen向上推动,所以你Activity的view的根树的尺寸是没有变化的。在这种情况下,你也就无法得知键盘的尺寸,对根view的作相应的推移。全屏下的键盘无法Resize的问题从2.1就已经存在了,直到现在google还未给予解决。

如果你想了解android 软键盘普通情况下显示与隐藏的问题,你可以了解这篇博客android 软键盘的显示与隐藏问题的研究,它可以帮助你解决在非全屏下,软键盘的显示时,你不能很好地控制布局的问题。

感谢Ricardo提供的轮子,他在stackoverflow找到了解决方案。有人已经封装好了该类,你只需引用就OK了,我们来看下这个帮助类。

帮助类源码:

//Workaround to get adjustResize functionality for input methos when the fullscreen mode is on
//found by Ricardo
//taken from http://stackoverflow.com/a/19494006

import android.app.Activity;
import android.graphics.Rect;
import android.view.View;
import android.view.ViewTreeObserver;
import android.widget.FrameLayout;

public class AndroidBug5497Workaround {

    // For more information, see https://code.google.com/p/android/issues/detail?id=5497
    // To use this class, simply invoke assistActivity() on an Activity that already has its content view set.

    public static void assistActivity (Activity activity) {
        new AndroidBug5497Workaround(activity);
    }

    private View mChildOfContent;
    private int usableHeightPrevious;
    private FrameLayout.LayoutParams frameLayoutParams;

    private AndroidBug5497Workaround(Activity activity) {
        FrameLayout content = (FrameLayout) activity.findViewById(android.R.id.content);
        mChildOfContent = content.getChildAt(0);
        mChildOfContent.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
            public void onGlobalLayout() {
                possiblyResizeChildOfContent();
            }
        });
        frameLayoutParams = (FrameLayout.LayoutParams) mChildOfContent.getLayoutParams();
    }

    private void possiblyResizeChildOfContent() {
        int usableHeightNow = computeUsableHeight();
        if (usableHeightNow != usableHeightPrevious) {
            int usableHeightSansKeyboard = mChildOfContent.getRootView().getHeight();
            int heightDifference = usableHeightSansKeyboard - usableHeightNow;
            if (heightDifference > (usableHeightSansKeyboard/4)) {
                // keyboard probably just became visible
                frameLayoutParams.height = usableHeightSansKeyboard - heightDifference;
            } else {
                // keyboard probably just became hidden
                frameLayoutParams.height = usableHeightSansKeyboard;
            }
            mChildOfContent.requestLayout();
            usableHeightPrevious = usableHeightNow;
        }
    }

    private int computeUsableHeight() {
        Rect r = new Rect();
        mChildOfContent.getWindowVisibleDisplayFrame(r);
        return (r.bottom - r.top);
    }

}

可以从源码看到其中的原理。

1.利用viewTreeobserver来监听View根树的变化。一旦键盘显示或隐藏都会引起addOnGlobalLayoutListener()方法调用。

2.计算Activtiy可视区域的高度,然后与上次可视区域高度进行比较,若相等,界面出现在变化。

3.如果界面出现变化,计算可视区域高度visibleHeight与Activity根view的高度rootHeight之差heightDifference。

4.如果heightDifference > (rootHeight / 4), 则认为键盘显示,否则认为键盘隐藏。

5.根据键盘变化的状态,对Activity的contentView进行高度属性作出改变。

至此,你已经完成了对键盘显示或隐藏对contentView的Resize了。

使用方法

在你的Activity的oncreate()方法里调用AndroidBug5497Workaround.assistActivity(this);即可。注意:在setContentView(R.layout.xxx)之后调用。

例子源码

android 软键盘在全屏下的布局计算问题,布布扣,bubuko.com

时间: 2024-10-10 21:44:21

android 软键盘在全屏下的布局计算问题的相关文章

完美解决android软键盘监听

最近在做应用性能调优,发现在一个包含有输入框的Activity中,当软键盘弹出的时候,如果直接finish掉此Activity,那么在返回到上一个Activity时,界面的渲染会由于软键盘没有及时的收起而出现卡顿的情况. 很不友好. 于是,本着geek的精神,做就做到极致,就尝试着对这一块做优化. 借助网上一些知识的分享,同时结合自己的理解,最终应用到项目中. 直接上代码.. 首先,在manifest文件中声明此Activity的windowSoftInputMode属性, 1 android:

完美解决android软键盘监听1

最近在做应用性能调优,发现在一个包含有输入框的Activity中,当软键盘弹出的时候,如果直接finish掉此Activity,那么在返回到上一个Activity时,界面的渲染会由于软键盘没有及时的收起而出现卡顿的情况. 很不友好. 于是,本着geek的精神,做就做到极致,就尝试着对这一块做优化. 借助网上一些知识的分享,同时结合自己的理解,最终应用到项目中. 直接上代码.. 首先,在manifest文件中声明此Activity的windowSoftInputMode属性,      andro

Android编程实现WebView全屏播放的方法

这篇文章主要介绍了Android编程实现WebView全屏播放的方法,结合实例形式较为详细的分析了Android实现WebView全屏播放的布局与功能相关技巧,需要的朋友可以参考下! 本文实例讲述了Android编程实现WebView全屏播放的方法.分享给大家供大家参考,具体如下: 最近因为项目要用webview加载html5的视频,开始不能全屏播,做了很久才做出来!那按我的理解说下怎么实现全屏吧. 首先写布局文件activity_main.xml: <LinearLayout xmlns:an

Android UI体验之全屏沉浸式透明状态栏效果

前言: Android 4.4之后谷歌提供了沉浸式全屏体验, 在沉浸式全屏模式下, 状态栏. 虚拟按键动态隐藏, 应用可以使用完整的屏幕空间, 按照 Google 的说法, 给用户一种 身临其境 的体验.而Android 5.0之后谷歌又提出了 ColorPalette 的概念,让开发者可以自己设定系统区域的颜色,使整个 App 的颜色风格和系统的颜色风格保持统一.今天学习总结一下如何实现Android 4.4以上全屏沉浸式透明状态栏效果.先看下预期效果: 首先现分清楚哪部分是状态栏,哪部分是导

【转载】android软键盘的一些控制

原文地址:http://blog.csdn.net/wang_shaner/article/details/8467688 "EditText + Button"  形成一个 "输入+按键响应" 的案例在android编程中是最常见不过的了. 但还有一些细节需要注意: 在EditText输入后,点击Button进行请求,软键盘应该自行消失 在EditText输入后,不点击Button进行请求,而是直接点击软键盘上的"回车",那么也应该能够正常响应

攻克Android软键盘的疑难杂症

系列教程:推翻自己和过往,重学自定义View 自定义View系列教程01–常用工具介绍 自定义View系列教程02–onMeasure源码详尽分析 自定义View系列教程03–onLayout源码详尽分析 自定义View系列教程04–Draw源码分析及其实践 自定义View系列教程05–示例分析 自定义View系列教程06–详解View的Touch事件处理 自定义View系列教程07–详解ViewGroup分发Touch事件 自定义View系列教程08–滑动冲突的产生及其处理 在Activity

关于android软键盘enter键的替换与事件监听

android软键盘事件监听enter键 软件盘的界面替换只有一个属性android:imeOptions,这个属性的可以取的值有 normal,actionUnspecified,actionNone,actionGo,actionSearch,actionSend,actionNext,actionDone, 例如当值为actionNext时enter键外观变成一个向下箭头,而值为actionDone时enter键外观则变成了“完成”两个字. 我们也可以重写enter的事件,方法如下 Jav

android 软键盘回车键捕获

EditText editText2 = (EditText)findViewById(R.id.txtTest2); editText2.setOnEditorActionListener(new OnEditorActionListener() { @Override public boolean onEditorAction(TextView arg0, int arg1, KeyEvent arg2) { if (arg1 == EditorInfo.IME_ACTION_UNSPECI

android软键盘enter键

enter键,回车键,电脑键盘上enter键就有多种响应.android软键盘也不例外 你在EditText上输入以后,想在下一行输入框输入,可能需要去点击下一行输入框,让它获取焦点,也可能要隐藏软键盘,在点击输入框,弹出软键盘. 或者已经到了最后一行输入框,输入完毕以后,要点击登录,注册,或者链接按钮,可能要去隐藏它,感觉操作狠繁琐.用户体验不好,有没有解决办法呢? 其实可以利用软键盘的enter键来解决上面的体验问题. 软键盘,最常用的enter键事件有: 把EditText的Ime Opt