-
Star
(156)
You must be signed in to star a gist -
Fork
(39)
You must be signed in to fork a gist
-
-
Save felHR85/6070f643d25f5a0b3674 to your computer and use it in GitHub Desktop.
| /* | |
| * Author: Felipe Herranz ([email protected]) | |
| * Contributors:Francesco Verheye ([email protected]) | |
| * Israel Dominguez ([email protected]) | |
| */ | |
| 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 ([email protected]) | |
| */ | |
| 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 ([email protected]) | |
| */ | |
| @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(); | |
| } | |
| } | |
| } | |
| } |
| /* | |
| * Android Manifest: android:windowSoftInputMode="adjustResize" | |
| */ | |
| /* | |
| Somewhere else in your code | |
| */ | |
| RelativeLayout mainLayout = findViewById(R.layout.main_layout); // You must use the layout root | |
| InputMethodManager im = (InputMethodManager) getSystemService(Service.INPUT_METHOD_SERVICE); | |
| /* | |
| Instantiate and pass a callback | |
| */ | |
| SoftKeyboard softKeyboard; | |
| softKeyboard = new SoftKeyboard(mainLayout, im); | |
| softKeyboard.setSoftKeyboardCallback(new SoftKeyboard.SoftKeyboardChanged() | |
| { | |
| @Override | |
| public void onSoftKeyboardHide() | |
| { | |
| // Code here | |
| } | |
| @Override | |
| public void onSoftKeyboardShow() | |
| { | |
| // Code here | |
| } | |
| }); | |
| /* | |
| Open or close the soft keyboard easily | |
| */ | |
| softKeyboard.openSoftKeyboard(); | |
| softKeyboard.closeSoftKeyboard(); | |
| /* Prevent memory leaks: | |
| */ | |
| @Override | |
| public void onDestroy() | |
| { | |
| super.onDestroy(); | |
| softKeyboard.unRegisterSoftKeyboardCallback(); | |
| } |
This does not work properly with fragments. Keyboard show method is being called but the Hide method is not being called. For Activity it is working fine.
@arshu-dev did you finally get the solution?
It works. Thank you! 💯
I have edittext in listview items .After back press when one item's edittext has focus and keypad is open ,method hidekeypad is not calling.
This class I want to use in listview but it is not working pls help for same
Here is Kotlin friendly change :)
https://gist.github.com/stasbar/095cb359846c225156fb15b3cc1eed86
Your code was not worked for me :'(
SoftKeyboard.SoftKeyboardChanged()
this method wasn't called ??
I use redmi note 4x, API 24
Guys it doen't work don't spent time on that
thank you very much.
Is there a Kotlin version of this?
thank you very much. it resolved my hard issues.