How do I detect if software keyboard is visible on Android Device or not?

前端 未结 30 1390
情书的邮戳
情书的邮戳 2020-11-22 10:59

Is there a way in Android to detect if the software (a.k.a. \"soft\") keyboard is visible on screen?

相关标签:
30条回答
  • 2020-11-22 11:32

    I used this as a basis: http://www.ninthavenue.com.au/how-to-check-if-the-software-keyboard-is-shown-in-android

    /**
    * To capture the result of IMM hide/show soft keyboard
    */
    public class IMMResult extends ResultReceiver {
         public int result = -1;
         public IMMResult() {
             super(null);
    }
    
    @Override 
    public void onReceiveResult(int r, Bundle data) {
        result = r;
    }
    
    // poll result value for up to 500 milliseconds
    public int getResult() {
        try {
            int sleep = 0;
            while (result == -1 && sleep < 500) {
                Thread.sleep(100);
                sleep += 100;
            }
        } catch (InterruptedException e) {
            Log.e("IMMResult", e.getMessage());
        }
        return result;
    }
    }
    

    Then wrote this method:

    public boolean isSoftKeyboardShown(InputMethodManager imm, View v) {
    
        IMMResult result = new IMMResult();
        int res;
    
        imm.showSoftInput(v, 0, result);
    
        // if keyboard doesn't change, handle the keypress
        res = result.getResult();
        if (res == InputMethodManager.RESULT_UNCHANGED_SHOWN ||
                res == InputMethodManager.RESULT_UNCHANGED_HIDDEN) {
    
            return true;
        }
        else
            return false;
    
    }
    

    You may then use this to test all fields (EditText, AutoCompleteTextView, etc) that may have opened a softkeyboard:

        InputMethodManager imm = (InputMethodManager) getActivity().getSystemService(Context.INPUT_METHOD_SERVICE);
        if(isSoftKeyboardShown(imm, editText1) | isSoftKeyboardShown(imm, autocompletetextview1))
            //close the softkeyboard
            imm.toggleSoftInput(InputMethodManager.SHOW_FORCED, 0);
    

    Addmittely not an ideal solution, but it gets the job done.

    0 讨论(0)
  • 2020-11-22 11:33

    This should work if you need to check keyboard status:

    fun Activity.isKeyboardOpened(): Boolean {
        val r = Rect()
    
        val activityRoot = getActivityRoot()
        val visibleThreshold = dip(UiUtils.KEYBOARD_VISIBLE_THRESHOLD_DP)
    
        activityRoot.getWindowVisibleDisplayFrame(r)
    
        val heightDiff = activityRoot.rootView.height - r.height()
    
        return heightDiff > visibleThreshold;
    }
    
    fun Activity.getActivityRoot(): View {
        return (findViewById<ViewGroup>(android.R.id.content)).getChildAt(0);
    }
    

    Where UiUtils.KEYBOARD_VISIBLE_THRESHOLD_DP = 100 and dip() is an anko func that convert dpToPx:

    fun dip(value: Int): Int {
        return (value * Resources.getSystem().displayMetrics.density).toInt()
    }
    
    0 讨论(0)
  • 2020-11-22 11:33

    Try this code it's really working if KeyboardShown is Shown then this function return true value....

    private final String TAG = "TextEditor";
    private TextView mTextEditor;
    
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_editor);
        mTextEditor = (TextView) findViewById(R.id.text_editor);
        mTextEditor.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
            @Override
            public void onGlobalLayout() {
                isKeyboardShown(mTextEditor.getRootView());
            }
        });
    }
    
    private boolean isKeyboardShown(View rootView) {
        /* 128dp = 32dp * 4, minimum button height 32dp and generic 4 rows soft keyboard */
        final int SOFT_KEYBOARD_HEIGHT_DP_THRESHOLD = 128;
    
        Rect r = new Rect();
        rootView.getWindowVisibleDisplayFrame(r);
        DisplayMetrics dm = rootView.getResources().getDisplayMetrics();
        /* heightDiff = rootView height - status bar height (r.top) - visible frame height (r.bottom - r.top) */
        int heightDiff = rootView.getBottom() - r.bottom;
        /* Threshold size: dp to pixels, multiply with display density */
        boolean isKeyboardShown = heightDiff > SOFT_KEYBOARD_HEIGHT_DP_THRESHOLD * dm.density;
    
        Log.d(TAG, "isKeyboardShown ? " + isKeyboardShown + ", heightDiff:" + heightDiff + ", density:" + dm.density
                + "root view height:" + rootView.getHeight() + ", rect:" + r);
    
        return isKeyboardShown;
    }
    
    0 讨论(0)
  • 2020-11-22 11:33

    Answer of @iWantScala is great but not working for me
    rootView.getRootView().getHeight() always has the same value

    one way is to define two vars

    private int maxRootViewHeight = 0;
    private int currentRootViewHeight = 0;
    

    add global listener

    rootView.getViewTreeObserver()
        .addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
            @Override
            public void onGlobalLayout() {
                currentRootViewHeight = rootView.getHeight();
                if (currentRootViewHeight > maxRootViewHeight) {
                    maxRootViewHeight = currentRootViewHeight;
                }
            }
        });
    

    then check

    if (currentRootViewHeight >= maxRootViewHeight) {
        // Keyboard is hidden
    } else {
        // Keyboard is shown
    }
    

    works fine

    0 讨论(0)
  • 2020-11-22 11:34

    There's finally a direct way starting from Android R based on Kotlin now.

     val imeInsets = view.rootWindowInsets.getInsets(Type.ime()) 
        if (imeInsets.isVisible) { 
         //Ime is visible
         //Lets move our view by the height of the IME
         view.translationX = imeInsets.bottom }
    
    0 讨论(0)
  • 2020-11-22 11:34
    final View activityRootView = findViewById(R.id.rootlayout);
    activityRootView.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
            @Override
            public void onGlobalLayout() {
    
                Rect r = new Rect();
                activityRootView.getWindowVisibleDisplayFrame(r);
    
                int screenHeight = activityRootView.getRootView().getHeight();
                Log.e("screenHeight", String.valueOf(screenHeight));
                int heightDiff = screenHeight - (r.bottom - r.top);
                Log.e("heightDiff", String.valueOf(heightDiff));
                boolean visible = heightDiff > screenHeight / 3;
                Log.e("visible", String.valueOf(visible));
                if (visible) {
                    Toast.makeText(LabRegister.this, "I am here 1", Toast.LENGTH_SHORT).show();
                } else {
                    Toast.makeText(LabRegister.this, "I am here 2", Toast.LENGTH_SHORT).show();
                }
            }
    });
    
    0 讨论(0)
提交回复
热议问题