Saturday, February 1, 2020

Aleksandr Koscheev


LOOKING FOR A JOB

Right now I am in Cancún, Mexico.

Phone (+521) 998 169 2213


Russian phone (SMS only) (+7) 910 480 7885


Skype: ru.alxr


Email aleksandr.koscheev@gmail.com

LinkedIn profile: https://mx.linkedin.com/in/aleksandr-koscheev-b7260062

Looking for long-time job in Android development

@Deprecated Skype:  tech_support_jetpc

Friday, December 23, 2016

How to intercept event Soft keyboard shown/hidden

This is solution that is composed of code from SO and my enhancement to support various API levels.
Inspired by SO post http://stackoverflow.com/questions/2150078/how-to-check-visibility-of-software-keyboard-in-android

Updated 1/24/2017

Preparation class:

package my.package.utils;

import android.graphics.Rect;
import android.os.Build;
import android.view.View;
import android.view.ViewTreeObserver;

import java.util.LinkedList;
import java.util.List;

public class SoftKeyboardStateWatcher implements ViewTreeObserver.OnGlobalLayoutListener {

    public interface SoftKeyboardStateListener {
        void onSoftKeyboardOpened(int keyboardHeightInPx);

        void onSoftKeyboardClosed();
    }

    private SoftKeyboardStateListener listener;

    private final View activityRootView;
    private boolean isSoftKeyboardOpened;
    private boolean isFirstTime = true;
    private boolean isSecondTime = true;
    private int firstValue;
    private int resize;
    private boolean isResizeAllowed;

    public SoftKeyboardStateWatcher(View activityRootView, SoftKeyboardStateListener listener) {
        this(activityRootView, false);
        this.listener = listener;
    }

    private SoftKeyboardStateWatcher(View activityRootView, boolean isSoftKeyboardOpened) {
        this.activityRootView = activityRootView;
        this.isSoftKeyboardOpened = isSoftKeyboardOpened;
        activityRootView.getViewTreeObserver().addOnGlobalLayoutListener(this);
    }

    private Timer timer;
    private boolean trick;

    @Override    public void onGlobalLayout() {
        final Rect r = new Rect();
        //r will be populated with the coordinates of your view that area still visible.        activityRootView.getWindowVisibleDisplayFrame(r);
        final int heightDiff = activityRootView.getRootView().getHeight() - (r.bottom - r.top);
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
            if (isFirstTime) {
                firstValue = heightDiff;
                isFirstTime = false;
                timer = new Timer();
                timer.schedule(new TimerTask() {
                    @Override                    public void run() {
                        if (isSecondTime) {
                            isSecondTime = false;
                            //firstValue = 0;                            new Handler(Looper.getMainLooper()).post(new Runnable() {
                                @Override                                public void run() {
                                    if (listener == null) return;
                                    int statusBarHeight = getStatusBarHeight();
                                    int navBarHeight = getNavBarHeight();
                                    if (heightDiff <= statusBarHeight + navBarHeight) return;
                                    Utils.log(SoftKeyboardStateWatcher.this, "TRIGGER BY TIMER");
                                    isSoftKeyboardOpened = true;
                                    trick = true;
                                    firstValue = statusBarHeight + navBarHeight;
                                    notifyOnSoftKeyboardOpened(heightDiff);
                                }
                            });

                        }
                    }
                }, 500L);

            } else {
                if (timer != null) {
                    timer.cancel();
                    timer.purge();
                    timer = null;
                }
                if (isSecondTime) {
                    isSecondTime = false;
                }
            }
            if (isSecondTime) return;
            if (!isSoftKeyboardOpened && heightDiff > firstValue && heightDiff > getStatusBarHeight() + getNavBarHeight()) { // if more than 100 pixels, its probably a keyboard...                isSoftKeyboardOpened = true;
                notifyOnSoftKeyboardOpened(heightDiff);
            } else {
                if (isSoftKeyboardOpened && trick) {
                    if (heightDiff < 100 && firstValue == 0) firstValue = heightDiff;
                }
                if (isSoftKeyboardOpened && heightDiff <= firstValue) {
                    isSoftKeyboardOpened = false;
                    notifyOnSoftKeyboardClosed();
                }
            }
        } else {
            if (!isSoftKeyboardOpened && heightDiff > 100) { // if more than 100 pixels, its probably a keyboard...                isSoftKeyboardOpened = true;
                notifyOnSoftKeyboardOpened(heightDiff);
            } else if (isSoftKeyboardOpened && heightDiff < 100) {
                isSoftKeyboardOpened = false;
                notifyOnSoftKeyboardClosed();
            }
        }
    }

    private int mKeyboardHeight;

    private void notifyOnSoftKeyboardOpened(int keyboardHeightInPx) {
        if (listener == null) return;
        mKeyboardHeight = keyboardHeightInPx - firstValue;
        listener.onSoftKeyboardOpened(keyboardHeightInPx);
        scrollBy(mKeyboardHeight);
    }

    private void notifyOnSoftKeyboardClosed() {
        if (listener == null) return;
        listener.onSoftKeyboardClosed();
        scrollBy(-mKeyboardHeight);
    }

    public void removeSoftKeyboardStateListener() {
        listener = null;
    }

    private int getStatusBarHeight() {
        int result = 0;
        Resources resources = activityRootView.getResources();
        int resourceId = resources.getIdentifier("status_bar_height", "dimen", "android");
        if (resourceId > 0) {
            result = resources.getDimensionPixelSize(resourceId);
        }
        return result;
    }

    private  int getNavBarHeight(){
        Resources resources = activityRootView.getResources();
        int resourceId = resources.getIdentifier("navigation_bar_height", "dimen", "android");
        if (resourceId > 0) {
            return resources.getDimensionPixelSize(resourceId);
        }
        return 0;
    }
}

The next step:
Your activity must implement SoftKeyboardStateWatcher.SoftKeyboardStateListener

Declare in your activity

protected SoftKeyboardStateWatcher mSoftKeyboardStateWatcher;

And run following code in onCreate:

int rootId = getRootId();//here you must supply root View id
View root;
if (rootId == 0 || (root = findViewById(rootId)) == null) return;
mSoftKeyboardStateWatcher = new SoftKeyboardStateWatcher(root);
mSoftKeyboardStateWatcher.addSoftKeyboardStateListener(AbstractActivity.this);

Now you have these methods:

@Overridepublic void onSoftKeyboardOpened(int keyboardHeightInPx) {
}

@Overridepublic void onSoftKeyboardClosed() {
}

Also do not forget to remove listener:

@Overridepublic void onDestroy() {
    if (mSoftKeyboardStateWatcher != null)
        mSoftKeyboardStateWatcher.removeSoftKeyboardStateListener(this);
    super.onDestroy();
}