Android:检测软键盘是否打开

Android:检测软键盘是否打开,android,view,scroll,Android,View,Scroll,当软键盘打开时,我想要一个向下滚动至底部的滚动视图 为此,我可以使用:fullScroll(View.FOCUS\u DOWN) 但是,在软键盘打开事件触发后,如何启动该命令?对于android开发人员来说,似乎不可能执行您想要的操作。您可能需要重新检查您正在做的事情的用例。也许其中一个标志对你有用。观察日期,你可能有一个问题的解决方案,否则: 以下是我对另一个相关问题的回答: 但为了避免死链接,我在这里复制了完整的响应: 请检查活动的配置更改 这适用于您的AndroidManifest.xml

当软键盘打开时,我想要一个向下滚动至底部的滚动视图

为此,我可以使用:fullScroll(View.FOCUS\u DOWN)


但是,在软键盘打开事件触发后,如何启动该命令?

对于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 */
}