android 隐藏键盘时ui延迟恢复,android 软键盘的显示与隐藏问题的研究

在android中,常常会和输入法的软件键盘交互。在Manifest文件中,系统给activity的一个属性-windowSoftInputMode来控制输入法的显示方式。

该属性提供了Activity的window与软键盘的window交互的方式。这里的属性设置有双方面的影响:

1.软键盘的显示与隐藏。-当Activity界面成为用户的焦点时,或隐藏或显示。

2。

对Activty的主window窗体进行调整。或者将Activity的window窗体调小以便为软键盘腾出空间,或者当Activity的部分window被软件盖住时,移动Activity的内容以便用户可以看到当前的焦点。

你至少要从下列属性值选取一项对其设置,要么是”state...“,要么是”adjust...“。

你能够设置多个值。设置不同的属性值。要用|进行分开。

比方:

以下是对属性的值的描写叙述。

描写叙述

”stateUnSpecified“

不指定软件的状态(显示或隐藏)。系统会依据主题中的设置来选择对应的状态。 该属性软键盘的默认设置。

”stateUnchnaged“

总是保持上次软键盘的状态。当Activity进入到最前端时,不论是它上次它是显示或隐藏。保持不变。

”stateHidden“

当用户进入目标Activity时。软键盘保持隐藏状态。这里的Activity是用户是向前进入Activity,而不是因为退出其他Activity退回到目标Activity。

”stateVisible“

仅仅有条件合适(当用户前进进入到Activity的主window),就会显示键盘

”stateAlawaysVisible“

当用户选择进入目标Activity时。软键盘被设置为可见的。这里的Activity是用户向前进入的Activity,而不是因为退出其他Activity而回到目标Activity

"adjustUnspecified"

不指定是否去调整Activity的界面。或者调整Activity窗体的大小以便为软键盘腾出空间或者移动窗体的内容来屏幕上当前的焦点可见。系统会自己主动选择当中一种模式,这依赖于窗体是包括能够滑动其内容的view.如有这种视图,窗体的大小就会被调整。在这种假定的情况下,非常小的滑动就能够使用窗体的内容可见。

该属性是主windowr默认设置。

”adjustResize“

Activity的窗体总是被调整其大小以便为软键盘腾出空间。

”adjustPan“

Activity的主窗体不会被调整其大小以便为软键盘腾出空间。相反,窗体的内容会被自己主动移动以便当前的焦点不会被软键盘遮住,用户能够总是看到他输入的内容。

这个值一般用于用户非常少想调整窗体的大小的情况下。由于用户可能须要关闭软键盘来与窗体的其他部分进行交互。

从上面系统的描写叙述了解了系统在处理两个交互时都显示Activity和软键盘都是看作window窗体来处理的。

非常多的时候,我们都希望可以监听到软件键盘的显示与关闭状态。比方下图的情况,

你有一个登录界面是这样设计的

83ffddc409baf6a84eab3ceb86059190.png

你希望登录时它是这种,

4d7cd11c63b6da63cd7f7d098ea1a9e9.png

然后你去尝试给activity的windowSoftInputMode属性加上值,当你加上 adjustResize时。它是这种

8d04de0fb63501e415cadef737883d7e.png

你不甘心。你将adjustResize改动成adjustPan,结果是这种

06ecc82d7ec6a360bd0e7bd2a74afc6c.png

没有办法。仅仅有靠我们自己来监听键盘的显示或隐藏来动态改变布局。如今的问题是怎么监听到键盘的动态改变呢。系统并没有提供对应的方法。我们能够通过两种方法来实现。

1.在adjustResize属性下。activity的窗体大小会发生改变,而窗体中的layout的大小也必定后会发生改变。

当view大小发生改变时,必定会引起onSizeChanged(int, int, int, int)的回调。所以可能自己定义一个Layout。来监測onSizeChanged()函数的回调。然后在当中的作对应的处理。

这种方法也是网上传的最多的方法。

2.借助ViewTreeOberserver类。ViewTreeOberserver能够用来注冊一个监听器。它能监听view树的全局变化。

这些变化包含但不限于,整个View的布局,绘制传递的源头,触摸模式的变化。

第一种方法的实现:

自己定义一个Layout。以RelativeLayout为例,

能够在onSizeChanged(intw,inth,intoldw,intoldh)方法里监听界面大小的变化,然后在该方法里定义回调函数。当监听到键盘被调出时,将键盘向上推一段距离,这样将登录键显示出来。

package com.example.keyboardlistener;

import android.content.Context;

import android.util.AttributeSet;

import android.util.Log;

import android.widget.RelativeLayout;

public class KeyboardLayout extends RelativeLayout {

private onSizeChangedListener mChangedListener;

private static final String TAG ="KeyboardLayoutTAG";

private boolean mShowKeyboard = false;

public KeyboardLayout(Context context, AttributeSet attrs, int defStyle) {

super(context, attrs, defStyle);

// TODO Auto-generated constructor stub

}

public KeyboardLayout(Context context, AttributeSet attrs) {

super(context, attrs);

// TODO Auto-generated constructor stub

}

public KeyboardLayout(Context context) {

super(context);

// TODO Auto-generated constructor stub

}

@Override

protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {

// TODO Auto-generated method stub

super.onMeasure(widthMeasureSpec, heightMeasureSpec);

Log.d(TAG, "onMeasure-----------");

}

@Override

protected void onLayout(boolean changed, int l, int t, int r, int b) {

// TODO Auto-generated method stub

super.onLayout(changed, l, t, r, b);

Log.d(TAG, "onLayout-------------------");

}

@Override

protected void onSizeChanged(int w, int h, int oldw, int oldh) {

// TODO Auto-generated method stub

super.onSizeChanged(w, h, oldw, oldh);

Log.d(TAG, "--------------------------------------------------------------");

Log.d(TAG, "w----" + w + "\n" + "h-----" + h + "\n" + "oldW-----" + oldw + "\noldh----" + oldh);

if (null != mChangedListener && 0 != oldw && 0 != oldh) {

if (h < oldh) {

mShowKeyboard = true;

} else {

mShowKeyboard = false;

}

mChangedListener.onChanged(mShowKeyboard);

Log.d(TAG, "mShowKeyboard----- " + mShowKeyboard);

}

}

public void setOnSizeChangedListener(onSizeChangedListener listener) {

mChangedListener = listener;

}

interface onSizeChangedListener{

void onChanged(boolean showKeyboard);

}

}

在主Activity里创建一个Handler。当监听到布局发生变化时,通过Handler更新UI。

package com.example.keyboardlistener;

import android.app.Activity;

import android.os.Bundle;

import android.os.Handler;

import android.os.Message;

import android.util.Log;

import android.view.ViewTreeObserver.OnPreDrawListener;

import android.widget.Button;

import com.example.keyboardlistener.KeyboardLayout.onSizeChangedListener;

public class MainActivity extends Activity {

private static final String TAG = "KeyboardLayoutTAG";

private KeyboardLayout mRoot;

private Button mLogin;

private int mLoginBottom;

private static final int KEYBOARD_SHOW = 0X10;

private static final int KEYBOARD_HIDE = 0X20;

private boolean mGetBottom = true;

private Handler mHandler = new Handler() {

@Override

public void handleMessage(Message msg) {

// TODO Auto-generated method stub

super.handleMessage(msg);

switch (msg.what) {

case KEYBOARD_HIDE:

mRoot.setPadding(0, 0, 0, 0);

break;

case KEYBOARD_SHOW:

int mRootBottom = mRoot.getBottom();

Log.d(TAG, "the mLoginBottom is " + mLoginBottom);

mRoot.setPadding(0, mRootBottom - mLoginBottom, 0, 0);

break;

default:

break;

}

}

};

@Override

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_main);

getActionBar().hide();

mRoot = (KeyboardLayout) findViewById(R.id.root_view);

mLogin = (Button) findViewById(R.id.login);

mRoot.setOnSizeChangedListener(new onSizeChangedListener() {

@Override

public void onChanged(boolean showKeyboard) {

// TODO Auto-generated method stub

if (showKeyboard) {

mHandler.sendMessage(mHandler.obtainMessage(KEYBOARD_SHOW));

Log.d(TAG, "show keyboard");

} else {

mHandler.sendMessage(mHandler.obtainMessage(KEYBOARD_HIDE));

}

}

});

mRoot.getViewTreeObserver().addOnPreDrawListener(new OnPreDrawListener() {

@Override

public boolean onPreDraw() {

// TODO Auto-generated method stub

if (mGetBottom) {

mLoginBottom = mLogin.getBottom();//获取登录button的位置信息。

}

mGetBottom = false;

return true;

}

});

}

// @Override

// public boolean onCreateOptionsMenu(Menu menu) {

// // Inflate the menu; this adds items to the action bar if it is present.

// getMenuInflater().inflate(R.menu.main, menu);

// return true;

// }

}

另外一种方法的实现:

借助ViewTreeObserver类对你想监听的view加入OnGlobalLayoutListener监听器。然后在onGlobalLayout()方法里窗体的变化情况来推断键盘是否被调出来了。以下是ViewTreeObserver监听的部分的代码:

mRoot.getViewTreeObserver().addOnGlobalLayoutListener(new OnGlobalLayoutListener() {

@Override

public void onGlobalLayout() {

int offset = mRoot.getRootView().getHeight() - mRoot.getHeight();

//依据视图的偏移值来推断键盘是否显示

if (offset > 300) {

mHandler.sendMessage(mHandler.obtainMessage(KEYBOARD_SHOW));

} else {

mHandler.sendMessage(mHandler.obtainMessage(KEYBOARD_HIDE));

}

}

});

当中Handler的详细实现同上述结构中的Handler一样。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/397846.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

天才基本法_《天才基本法》强推!年度神仙小说,看完这本书我竟然爱上了数学...

《天才基本法》——长洱小说文案元宝的书评这个真的是本年度的神仙小说&#xff0c;讲述了女主回到少女时代&#xff0c;可以和他一直暗恋的数学天才重来一遍。女主让男主改变了觉得她碌碌无为的看法&#xff0c;也改变了自己的人生。本书最大的主角其实是数学&#xff01;天知…

dataTables插件使用

引用文件 <!-- DataTables CSS --> <link rel"stylesheet" type"text/css" href"http://cdn.datatables.net/1.10.7/css/jquery.dataTables.css"><!-- jQuery --> <script type"text/javascript" charset"u…

一行代码,发送邮件

朋友让我给他媳妇儿肚子里的孩子想个名字 走的越来越快了&#xff0c;有天看到一个论点关于说地域会影响人的一辈子。其实想想的确有这个理儿&#xff0c;这使我想起来每天早上挤地铁的时候&#xff0c;其中有一个A站的人总是特别彪悍的往里挤&#xff0c;但B站的人就是永远不会…

js call,apply,bind三个方法的区别

相同点&#xff1a; 都是能够改变this的指向 不同点&#xff1a; 1.call()&#xff1a;传参方式跟bind一样&#xff08;都是以逗号隔开的传参方式&#xff09;&#xff0c;但是跟apply&#xff08;以数组的形式传参&#xff09;不一样&#xff0c; 2.bind(): 此方法应用后的情形…

千年鸿蒙 盼尔来兮是什么意思,鸿蒙是什么意思_鸿蒙的意思和出处_我爱历史网...

鸿蒙&#xff0c;是一个汉语词语&#xff0c;亦作“鸿濛”。中国神话传说的远古时代&#xff0c;传说在盘古开天辟地之前&#xff0c;世界是一团混沌状&#xff0c;因此把那个时代称作鸿蒙时代&#xff0c;后来该词也常被用来泛指远古时代。引证解释亦作“鸿濛”。1、宇宙形成前…

python中调用万年历_python 打印万年历

题目&#xff1a;打印万年历已知条件闰年条件&#xff1a;能被4整除且不能被100整除&#xff0c;或者能被400整除1900年1月1日 是周一解题思路判断闰年;判断当月有多少天;这个月的1号是从周几开始的;格式化打印日历。解题代码#判断年份是否为闰年def is_leap_year(year):if (ye…

求水仙花数

求出所有的"水仙花数"&#xff0c;所谓"水仙花数"是指一个三位数&#xff0c;其各位数字立方和等于该数本身。 1 /**2 * 题目&#xff1a;打印出所有的"水仙花数"&#xff0c;所谓"水仙花数"是指一个三位数&#xff0c;其各位数字立方…

在VS2015中用C++创建DLL并用C#调用且同时实现对DLL的调试

from:http://m.blog.csdn.net/article/details?id51075023 在VS2015中先创建C#项目&#xff0c;然后再创建要编写的动态库DLL项目&#xff0c;这样做的好处是整个解决方案的编程环境是C#模式&#xff0c;这样就可以有很多智能的提示或快捷的编程方式在整个解决方案中都可以使用…

(转)CocosCreator零基础制作游戏《极限跳跃》二、制作游戏开始场景

CocosCreator零基础制作游戏《极限跳跃》二、制作游戏开始场景 我们刚刚分析了《极限跳跃》这款游戏&#xff0c;下面我们开始制作第一个游戏场景&#xff0c;也就是游戏的开始场景。 首先&#xff0c;打开CocosCreator&#xff0c;新建HelloWorld项目。选择项目路径&#xff0…

连接池超时配置_HttpClient连接池的一些思考

前言使用apache的httpclient进行http的交互处理已经很长时间了&#xff0c;而httpclient实例则使用了http连接池&#xff0c;想必大家也没有关心过连接池的管理。事实上&#xff0c;通过分析httpclient源码&#xff0c;发现它很优雅地隐藏了所有的连接池管理细节&#xff0c;开…

android界面布局错位,IOS 浏览器页面布局错位(如:点不到)的分析与解决

IOS 浏览器页面布局错位(如&#xff1a;点不到)的分析与解决IOS 浏览器软键盘的拉起与收缩、微信 IOS 浏览器底部导航条的显示与隐藏&#xff0c;很容易导致页面布局错位(相对窗体的绝对定位元素)&#xff1a;明明按钮在这里&#xff0c;却要在上面一点儿点击屏幕才能点到它明明…

做进度条 根据自己的数据显示进度

做了很多种方法 1&#xff1a; 线程 thread的方法 2&#xff1a; backGroundWorker的方法 3&#xff1a; 自定义线程类 4&#xff1a; 做一个进度条的窗体 通过自定义设置做&#xff08;最方便快捷&#xff09; public partial class waitingProcessbar : Form{public waitin…

视图和模型变换

视图变换&#xff0c;是指变换照相机的位置&#xff0c;角度。 模型变换&#xff0c;是指变换被照物体的位置&#xff0c;角度。 这两个变换&#xff0c;都会影响最终图形中&#xff0c;物体的位置&#xff0c;角度。而这两个变换&#xff0c;可以达到相同的效果。比如&#x…

phoenix的元数据一般存在哪里_Phoenix的一些问题

date: 2020-09-10 13:50:00updated: 2020-09-14 16:30:001. Phoenix索引全局索引&#xff1a;适合读多写少的场景。写数据时因为索引表分布在不同数据节点&#xff0c;跨节点数据传输带来巨大的性能消耗。全局索引必须是查询语句中所有列都包含在全局索引中&#xff0c;它才会生…

鸿蒙os全面升级,华为突然宣布,鸿蒙OS正式版6月底全面升级,幸福来得太突然...

原标题&#xff1a;华为突然宣布&#xff0c;鸿蒙OS正式版6月底全面升级&#xff0c;幸福来得太突然摘要&#xff1a;早在今年2月华为Mate X2折叠屏新品发布会上&#xff0c;余承东曾表示&#xff0c;鸿蒙OS正式版将于今年4月份全面上线。或许是因为华为宣布卖车分散了很多的精…

5-python学习——条件语句

5-python学习——条件语句 5-python学习——条件语句 条件语句if else形式if else条件语句说明 测试一下编程语言一般都由这么几个部分组成 变量条件分支语句循环语句函数这里要说的就是条件分支语句。 python的条件语句和shell脚本的非常像&#xff0c;也就是if else if else这…

eclipse启动失败:An internal error occurred during: reload maven project

2019独角兽企业重金招聘Python工程师标准>>> 1.找到workspace文件夹下的/.metadata文件夹&#xff0c;将其删除掉&#xff0c;然后在讲项目重新导入进去eclipse中。但是这个有一点不好的地方&#xff0c;之前对eclipse所做的配置也会恢复为默认配置 2.在.metadata下…

Quartz2D知识点聚合案例

Quartz2D知识点聚合 基本 //画图片UIImage *image [UIImage imageNamed:"阿狸头像"];[image drawInRect:rect];//字体NSString *title "标题";NSMutableDictionary *atr [NSMutableDictionary dictionary];atr[NSFontAttributeName] [UIFont systemFon…

skt7850鸿蒙策略,lol 英雄联盟 SKT状态回暖轻取外卡,SUP难挡Faker

MSI 第四日 SUP vs SKT双方bpBAN LISTBAN&#xff1a;SUP:流浪 牛头 豹女SKT&#xff1a;巴德 妖姬 鱼人PICKSUP:大树 男枪 冰女 卢锡安 锤石SKT&#xff1a;艾克 千珏 沙皇 EZ 布隆比赛开始&#xff0c;双方正常对线开局。前期下路锤石多次勾中ez&#xff0c;男枪也来逼出EZ布…

spring集成struts2

Struts2前身是WebWork&#xff0c;核心并没有改变&#xff0c;其实就是把WebWork改名为struts2&#xff0c;与Struts1一点关系没有。 Struts2中通过ObjectFactory接口实现创建及获取Action实例&#xff0c;类似于Spring的IoC容器&#xff0c;所以Action实例可以由ObjectFactory…