Android:检测软键盘是否打开
当软键盘打开时,我想要一个向下滚动至底部的滚动视图 为此,我可以使用:fullScroll(View.FOCUS\u DOWN)Android:检测软键盘是否打开,android,view,scroll,Android,View,Scroll,当软键盘打开时,我想要一个向下滚动至底部的滚动视图 为此,我可以使用:fullScroll(View.FOCUS\u DOWN) 但是,在软键盘打开事件触发后,如何启动该命令?对于android开发人员来说,似乎不可能执行您想要的操作。您可能需要重新检查您正在做的事情的用例。也许其中一个标志对你有用。观察日期,你可能有一个问题的解决方案,否则: 以下是我对另一个相关问题的回答: 但为了避免死链接,我在这里复制了完整的响应: 请检查活动的配置更改 这适用于您的AndroidManifest.xml
但是,在软键盘打开事件触发后,如何启动该命令?对于android开发人员来说,似乎不可能执行您想要的操作。您可能需要重新检查您正在做的事情的用例。也许其中一个标志对你有用。观察日期,你可能有一个问题的解决方案,否则: 以下是我对另一个相关问题的回答: 但为了避免死链接,我在这里复制了完整的响应: 请检查活动的配置更改 这适用于您的AndroidManifest.xml 这是你的活动课 您需要@Override活动的公共方法onConfigurationChanged(android.content.res.Configuration),以便能够处理以下值:
硬键盘隐藏,
键盘,
键盘隐藏 对于所有可能的值,请检查 你会看到这样的东西:
HARDKEYBOARDHIDDEN_NO
HARDKEYBOARDHIDDEN_UNDEFINED
HARDKEYBOARDHIDDEN_YES
KEYBOARDHIDDEN_NO
KEYBOARDHIDDEN_UNDEFINED
KEYBOARDHIDDEN_YES
KEYBOARD_12KEY
KEYBOARD_NOKEYS
KEYBOARD_QWERTY
KEYBOARD_UNDEFINED
public int hardKeyboardHidden A flag indicating whether the hard keyboard has been hidden.
public int keyboard The kind of keyboard attached to the device.
public int keyboardHidden A flag indicating whether any keyboard is available.
在这里,您还可以阅读以下内容:
HARDKEYBOARDHIDDEN_NO
HARDKEYBOARDHIDDEN_UNDEFINED
HARDKEYBOARDHIDDEN_YES
KEYBOARDHIDDEN_NO
KEYBOARDHIDDEN_UNDEFINED
KEYBOARDHIDDEN_YES
KEYBOARD_12KEY
KEYBOARD_NOKEYS
KEYBOARD_QWERTY
KEYBOARD_UNDEFINED
public int hardKeyboardHidden A flag indicating whether the hard keyboard has been hidden.
public int keyboard The kind of keyboard attached to the device.
public int keyboardHidden A flag indicating whether any keyboard is available.
更新:
下面是我所说内容的一个具体样本:
我希望这对您有所帮助我能够解决这一问题的唯一方法是设置我的活动的android:WindowsOfInputMode=“adjustResize”,然后在布局中嵌入一个自定义“检测器视图”,以处理容器大小的更改,并将其作为自定义事件传播(通过侦听器)以打开/关闭软键盘 下面的帖子描述了一种实现它的方法:这是我的解决方案: 1/一个简单的界面
public interface KeyboardVisibilityListener {
void onKeyboardVisibilityChanged(boolean keyboardVisible);
}
2/实用方法(将其放在您想要的地方,例如在名为KeyboardUtil
的类中)
对于这一点,我过去也是这么做的:
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.atomic.AtomicBoolean;
import android.os.Handler;
import android.os.Message;
import android.view.View;
import android.view.ViewGroup;
import android.view.inputmethod.InputMethodManager;
import android.widget.EditText;
public class SoftKeyboard implements View.OnFocusChangeListener
{
private static final int CLEAR_FOCUS = 0;
private ViewGroup layout;
private int layoutBottom;
private InputMethodManager im;
private int[] coords;
private boolean isKeyboardShow;
private SoftKeyboardChangesThread softKeyboardThread;
private List<EditText> editTextList;
private View tempView; // reference to a focused EditText
public SoftKeyboard(ViewGroup layout, InputMethodManager im)
{
this.layout = layout;
keyboardHideByDefault();
initEditTexts(layout);
this.im = im;
this.coords = new int[2];
this.isKeyboardShow = false;
this.softKeyboardThread = new SoftKeyboardChangesThread();
this.softKeyboardThread.start();
}
public void openSoftKeyboard()
{
if(!isKeyboardShow)
{
layoutBottom = getLayoutCoordinates();
im.toggleSoftInput(0, InputMethodManager.SHOW_IMPLICIT);
softKeyboardThread.keyboardOpened();
isKeyboardShow = true;
}
}
public void closeSoftKeyboard()
{
if(isKeyboardShow)
{
im.toggleSoftInput(InputMethodManager.HIDE_IMPLICIT_ONLY, 0);
isKeyboardShow = false;
}
}
public void setSoftKeyboardCallback(SoftKeyboardChanged mCallback)
{
softKeyboardThread.setCallback(mCallback);
}
public void unRegisterSoftKeyboardCallback()
{
softKeyboardThread.stopThread();
}
public interface SoftKeyboardChanged
{
public void onSoftKeyboardHide();
public void onSoftKeyboardShow();
}
private int getLayoutCoordinates()
{
layout.getLocationOnScreen(coords);
return coords[1] + layout.getHeight();
}
private void keyboardHideByDefault()
{
layout.setFocusable(true);
layout.setFocusableInTouchMode(true);
}
/*
* InitEditTexts now handles EditTexts in nested views
* Thanks to Francesco Verheye (verheye.francesco@gmail.com)
*/
private void initEditTexts(ViewGroup viewgroup)
{
if(editTextList == null)
editTextList = new ArrayList<EditText>();
int childCount = viewgroup.getChildCount();
for(int i=0; i<= childCount-1;i++)
{
View v = viewgroup.getChildAt(i);
if(v instanceof ViewGroup)
{
initEditTexts((ViewGroup) v);
}
if(v instanceof EditText)
{
EditText editText = (EditText) v;
editText.setOnFocusChangeListener(this);
editText.setCursorVisible(true);
editTextList.add(editText);
}
}
}
/*
* OnFocusChange does update tempView correctly now when keyboard is still shown
* Thanks to Israel Dominguez (dominguez.israel@gmail.com)
*/
@Override
public void onFocusChange(View v, boolean hasFocus)
{
if(hasFocus)
{
tempView = v;
if(!isKeyboardShow)
{
layoutBottom = getLayoutCoordinates();
softKeyboardThread.keyboardOpened();
isKeyboardShow = true;
}
}
}
// This handler will clear focus of selected EditText
private final Handler mHandler = new Handler()
{
@Override
public void handleMessage(Message m)
{
switch(m.what)
{
case CLEAR_FOCUS:
if(tempView != null)
{
tempView.clearFocus();
tempView = null;
}
break;
}
}
};
private class SoftKeyboardChangesThread extends Thread
{
private AtomicBoolean started;
private SoftKeyboardChanged mCallback;
public SoftKeyboardChangesThread()
{
started = new AtomicBoolean(true);
}
public void setCallback(SoftKeyboardChanged mCallback)
{
this.mCallback = mCallback;
}
@Override
public void run()
{
while(started.get())
{
// Wait until keyboard is requested to open
synchronized(this)
{
try
{
wait();
} catch (InterruptedException e)
{
e.printStackTrace();
}
}
int currentBottomLocation = getLayoutCoordinates();
// There is some lag between open soft-keyboard function and when it really appears.
while(currentBottomLocation == layoutBottom && started.get())
{
currentBottomLocation = getLayoutCoordinates();
}
if(started.get())
mCallback.onSoftKeyboardShow();
// When keyboard is opened from EditText, initial bottom location is greater than layoutBottom
// and at some moment equals layoutBottom.
// That broke the previous logic, so I added this new loop to handle this.
while(currentBottomLocation >= layoutBottom && started.get())
{
currentBottomLocation = getLayoutCoordinates();
}
// Now Keyboard is shown, keep checking layout dimensions until keyboard is gone
while(currentBottomLocation != layoutBottom && started.get())
{
synchronized(this)
{
try
{
wait(500);
} catch (InterruptedException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
}
currentBottomLocation = getLayoutCoordinates();
}
if(started.get())
mCallback.onSoftKeyboardHide();
// if keyboard has been opened clicking and EditText.
if(isKeyboardShow && started.get())
isKeyboardShow = false;
// if an EditText is focused, remove its focus (on UI thread)
if(started.get())
mHandler.obtainMessage(CLEAR_FOCUS).sendToTarget();
}
}
public void keyboardOpened()
{
synchronized(this)
{
notify();
}
}
public void stopThread()
{
synchronized(this)
{
started.set(false);
notify();
}
}
}
}
享受你的代码:)这对我很有用
parent.addOnLayoutChangeListener(new View.OnLayoutChangeListener() {
@Override
public void onLayoutChange(View v, int left, int top, int right, int bottom, int oldLeft, int oldTop, int oldRight, int oldBottom) {
boolean someHasFocus = false;
if(host.hasFocus())
someHasFocus = true;
if(folder.hasFocus())
someHasFocus = true;
if(user.hasFocus())
someHasFocus = true;
if(pass.hasFocus())
someHasFocus = true;
if(someHasFocus){
if(bottom>oldBottom){
// Keyboard Close
viewToHide.setVisibility(View.VISIBLE);
}else if(bottom<oldBottom){
// Keyboard Open
viewToHide.setVisibility(View.GONE);
}
}else{
// show
viewToHide.setVisibility(View.VISIBLE);
}
}
});
希望这能帮上忙这是我的解决办法。它不需要android:WindowsOfInputMode=“adjustResize”
public抽象类keyboard活动扩展活动{
公共静态最终整数最小键盘大小=100;
私人窗口;
私人视图mRootView;
私有int mKeyboardHeight=-1;
私有ViewTreeObserver.OnGlobalLayoutListener mGlobalLayoutListener=新ViewTreeObserver.OnGlobalLayoutListener(){
公众内部高度;
公共图书馆{
Rect r=新的Rect();
View=mRootWindow.getDecorView();
view.getWindowVisibleDisplayFrame(r);
如果(高度!=r.高度()){
int diff=高度-r.高度();
高度=r.高度();
if(数学abs(差异)>最小键盘尺寸){
int diff=高度-r.高度();
如果(高度!=0&&Math.abs(差异)>最小键盘尺寸){
mKeyboardHeight=数学绝对值(差值);
如果(差异>0){
onKeyboardOpen();
}否则{
onKeyboardClosed();
}
}
高度=r.高度();
}
}
};
KeyboardClosed()上的受保护抽象无效;
KeyboardOpen()上的受保护抽象无效;
/**
*若键盘至少显示一次,则应返回键盘高度;
*@返回键盘高度或-1
*/
受保护的整型getKeyboardHeight(){
返回mKeyboardHeight;
}
@凌驾
创建时的公共void(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
mRootWindow=getWindow();
mRootView=mRootWindow.getDecorView().findViewById(android.R.id.content);
}
@凌驾
受保护的void onStart(){
super.onStart();
mRootView.getViewTreeObserver().addOnGlobalLayoutListener(mGlobalLayoutListener);
}
@凌驾
受保护的void onStop(){
super.onStop();
mRootView.getViewTreeObserver().removeOnGlobalLayoutListener(mGlobalLayoutListener);
}
}
然后,我刚刚从这个活动扩展了我的活动,并覆盖了onKeyboardClosed/onKeyboardOpen方法。如果我删除下面的行,效果很好
if (mPreviousHeight != 0) {
/* other code is same, because
mPreviousHeight is 0 when it comes first */
}
这是硬键盘的一个例子,这对软键盘不起作用,没有办法知道。这真的让我很惊讶。@longhairedsi安卓系统中的软硬键盘是什么?2012年12月。是的,那就是2012年,安卓系统仍然没有很好的方法来通知软键盘是否可见。太棒了!@sebrock Same在2014年是2016年在这里:(差不多2017年了。我们有了新的模拟器、新的IDE,但仍然没有检查键盘状态的解决方案。2019年就到了。第一个人将在最近的将来在火星上迈出第一步。几周前,全世界都看到了带有可折叠触摸屏的设备。机器人无处不在。但我们仍然无法轻易地检测到Android中的键盘可见性。胡拉!!!我喜欢你的建议。.重要的是,这只适用于adjustResize,不是吗?你在这里可以看到此建议的其他要求吗?这是一个很好的方法,尽管我建议你介绍一种从
ViewTreeObserver
中删除先前添加的侦听器的方法(例如,如果您在片段
中使用此方法,并且该方法正在从活动
中分离)。对于android:inputType=“textPassword”失败
Neverthless a neight way!@User3我真的不明白这为什么会失败,这取决于输入类型。因为对于密码没有预测,而且您错过了最上面一行,请在5.0.1环境中尝试一下。这打破了支持设计库的android.support.design.widget.TextInputLayout
parent.addOnLayoutChangeListener(new View.OnLayoutChangeListener() {
@Override
public void onLayoutChange(View v, int left, int top, int right, int bottom, int oldLeft, int oldTop, int oldRight, int oldBottom) {
boolean someHasFocus = false;
if(host.hasFocus())
someHasFocus = true;
if(folder.hasFocus())
someHasFocus = true;
if(user.hasFocus())
someHasFocus = true;
if(pass.hasFocus())
someHasFocus = true;
if(someHasFocus){
if(bottom>oldBottom){
// Keyboard Close
viewToHide.setVisibility(View.VISIBLE);
}else if(bottom<oldBottom){
// Keyboard Open
viewToHide.setVisibility(View.GONE);
}
}else{
// show
viewToHide.setVisibility(View.VISIBLE);
}
}
});
android:windowSoftInputMode="stateHidden|adjustResize"
if (mPreviousHeight != 0) {
/* other code is same, because
mPreviousHeight is 0 when it comes first */
}