Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- package com.younglive.livestreaming.utils.view;
- /*
- * Author: Felipe Herranz (felhr85@gmail.com)
- * Contributors:Francesco Verheye (verheye.francesco@gmail.com)
- * Israel Dominguez (dominguez.israel@gmail.com)
- */
- 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;
- import java.lang.ref.WeakReference;
- import java.util.ArrayList;
- import java.util.List;
- import java.util.concurrent.atomic.AtomicBoolean;
- 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);
- this.softKeyboardThread.start();
- mHandler = new InnerHandler(this);
- }
- 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<>();
- 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 InnerHandler mHandler;
- private static class SoftKeyboardChangesThread extends Thread {
- WeakReference<SoftKeyboard> mSoftKeyboardWeakReference;
- private AtomicBoolean started;
- private SoftKeyboardChanged mCallback;
- public SoftKeyboardChangesThread(SoftKeyboard softKeyboard) {
- started = new AtomicBoolean(true);
- mSoftKeyboardWeakReference = new WeakReference<>(softKeyboard);
- }
- 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();
- }
- }
- if (mSoftKeyboardWeakReference.get() != null &&
- mSoftKeyboardWeakReference.get().mHandler != null) {
- int currentBottomLocation = mSoftKeyboardWeakReference.get().getLayoutCoordinates();
- // There is some lag between open soft-keyboard function and when it really appears.
- while(currentBottomLocation == mSoftKeyboardWeakReference.get().layoutBottom && started.get()) {
- currentBottomLocation = mSoftKeyboardWeakReference.get().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 >= mSoftKeyboardWeakReference.get().layoutBottom && started.get()) {
- currentBottomLocation = mSoftKeyboardWeakReference.get().getLayoutCoordinates();
- }
- // Now Keyboard is shown, keep checking layout dimensions until keyboard is gone
- while(currentBottomLocation != mSoftKeyboardWeakReference.get().layoutBottom && started.get()) {
- synchronized(this) {
- try {
- wait(500);
- } catch (InterruptedException e) {
- e.printStackTrace();
- }
- }
- currentBottomLocation = mSoftKeyboardWeakReference.get().getLayoutCoordinates();
- }
- if(started.get()) {
- mCallback.onSoftKeyboardHide();
- }
- // if keyboard has been opened clicking and EditText.
- if(mSoftKeyboardWeakReference.get().isKeyboardShow && started.get()) {
- mSoftKeyboardWeakReference.get().isKeyboardShow = false;
- }
- // if an EditText is focused, remove its focus (on UI thread)
- if(started.get()) {
- mSoftKeyboardWeakReference.get().mHandler.obtainMessage(CLEAR_FOCUS).sendToTarget();
- }
- }
- }
- }
- public void keyboardOpened()
- {
- synchronized(this)
- {
- notify();
- }
- }
- public void stopThread()
- {
- synchronized(this)
- {
- started.set(false);
- notify();
- }
- }
- }
- private static final class InnerHandler extends Handler {
- private WeakReference<SoftKeyboard> mSoftKeyboardWeakReference;
- private InnerHandler(SoftKeyboard softKeyboard) {
- mSoftKeyboardWeakReference = new WeakReference<>(softKeyboard);
- }
- @Override
- public void handleMessage(Message m) {
- switch(m.what) {
- case CLEAR_FOCUS:
- if(mSoftKeyboardWeakReference.get() != null &&
- mSoftKeyboardWeakReference.get().tempView != null) {
- mSoftKeyboardWeakReference.get().tempView.clearFocus();
- mSoftKeyboardWeakReference.get().tempView = null;
- mSoftKeyboardWeakReference.clear();
- }
- break;
- }
- }
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement