Guest User

Untitled

a guest
Aug 2nd, 2018
289
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 7.28 KB | None | 0 0
  1. /*
  2. * Author: Felipe Herranz (felhr85@gmail.com)
  3. * Contributors:Francesco Verheye (verheye.francesco@gmail.com)
  4. * Israel Dominguez (dominguez.israel@gmail.com)
  5. */
  6. import java.util.ArrayList;
  7. import java.util.List;
  8. import java.util.concurrent.atomic.AtomicBoolean;
  9.  
  10. import android.os.Handler;
  11. import android.os.Message;
  12. import android.view.View;
  13. import android.view.ViewGroup;
  14. import android.view.inputmethod.InputMethodManager;
  15. import android.widget.EditText;
  16.  
  17. public class SoftKeyboard implements View.OnFocusChangeListener
  18. {
  19. private static final int CLEAR_FOCUS = 0;
  20.  
  21. private ViewGroup layout;
  22. private int layoutBottom;
  23. private InputMethodManager im;
  24. private int[] coords;
  25. private boolean isKeyboardShow;
  26. private SoftKeyboardChangesThread softKeyboardThread;
  27. private List<EditText> editTextList;
  28.  
  29. private View tempView; // reference to a focused EditText
  30.  
  31. public SoftKeyboard(ViewGroup layout, InputMethodManager im)
  32. {
  33. this.layout = layout;
  34. keyboardHideByDefault();
  35. initEditTexts(layout);
  36. this.im = im;
  37. this.coords = new int[2];
  38. this.isKeyboardShow = false;
  39. this.softKeyboardThread = new SoftKeyboardChangesThread();
  40. this.softKeyboardThread.start();
  41. }
  42.  
  43.  
  44. public void openSoftKeyboard()
  45. {
  46. if(!isKeyboardShow)
  47. {
  48. layoutBottom = getLayoutCoordinates();
  49. im.toggleSoftInput(0, InputMethodManager.SHOW_IMPLICIT);
  50. softKeyboardThread.keyboardOpened();
  51. isKeyboardShow = true;
  52. }
  53. }
  54.  
  55. public void closeSoftKeyboard()
  56. {
  57. if(isKeyboardShow)
  58. {
  59. im.toggleSoftInput(InputMethodManager.HIDE_IMPLICIT_ONLY, 0);
  60. isKeyboardShow = false;
  61. }
  62. }
  63.  
  64. public void setSoftKeyboardCallback(SoftKeyboardChanged mCallback)
  65. {
  66. softKeyboardThread.setCallback(mCallback);
  67. }
  68.  
  69. public void unRegisterSoftKeyboardCallback()
  70. {
  71. softKeyboardThread.stopThread();
  72. }
  73.  
  74. public interface SoftKeyboardChanged
  75. {
  76. void onSoftKeyboardChange(boolean visible);
  77. }
  78.  
  79. private int getLayoutCoordinates()
  80. {
  81. layout.getLocationOnScreen(coords);
  82. return coords[1] + layout.getHeight();
  83. }
  84.  
  85. private void keyboardHideByDefault()
  86. {
  87. layout.setFocusable(true);
  88. layout.setFocusableInTouchMode(true);
  89. }
  90.  
  91. /*
  92. * InitEditTexts now handles EditTexts in nested views
  93. * Thanks to Francesco Verheye (verheye.francesco@gmail.com)
  94. */
  95. private void initEditTexts(ViewGroup viewgroup)
  96. {
  97. if(editTextList == null)
  98. editTextList = new ArrayList<EditText>();
  99.  
  100. int childCount = viewgroup.getChildCount();
  101. for(int i=0; i<= childCount-1;i++)
  102. {
  103. View v = viewgroup.getChildAt(i);
  104.  
  105. if(v instanceof ViewGroup)
  106. {
  107. initEditTexts((ViewGroup) v);
  108. }
  109.  
  110. if(v instanceof EditText)
  111. {
  112. EditText editText = (EditText) v;
  113. editText.setOnFocusChangeListener(this);
  114. editText.setCursorVisible(true);
  115. editTextList.add(editText);
  116. }
  117. }
  118. }
  119.  
  120. /*
  121. * OnFocusChange does update tempView correctly now when keyboard is still shown
  122. * Thanks to Israel Dominguez (dominguez.israel@gmail.com)
  123. */
  124. @Override
  125. public void onFocusChange(View v, boolean hasFocus)
  126. {
  127. if(hasFocus)
  128. {
  129. tempView = v;
  130. if(!isKeyboardShow)
  131. {
  132. layoutBottom = getLayoutCoordinates();
  133. softKeyboardThread.keyboardOpened();
  134. isKeyboardShow = true;
  135. }
  136. }
  137. }
  138.  
  139. // This handler will clear focus of selected EditText
  140. private final Handler mHandler = new Handler()
  141. {
  142. @Override
  143. public void handleMessage(Message m)
  144. {
  145. switch(m.what)
  146. {
  147. case CLEAR_FOCUS:
  148. if(tempView != null)
  149. {
  150. tempView.clearFocus();
  151. tempView = null;
  152. }
  153. break;
  154. }
  155. }
  156. };
  157.  
  158. private class SoftKeyboardChangesThread extends Thread
  159. {
  160. private AtomicBoolean started;
  161. private SoftKeyboardChanged mCallback;
  162.  
  163. public SoftKeyboardChangesThread()
  164. {
  165. started = new AtomicBoolean(true);
  166. }
  167.  
  168. public void setCallback(SoftKeyboardChanged mCallback)
  169. {
  170. this.mCallback = mCallback;
  171. }
  172.  
  173. @Override
  174. public void run()
  175. {
  176. while(started.get())
  177. {
  178. // Wait until keyboard is requested to open
  179. synchronized(this)
  180. {
  181. try
  182. {
  183. wait();
  184. } catch (InterruptedException e)
  185. {
  186. e.printStackTrace();
  187. }
  188. }
  189.  
  190. int currentBottomLocation = getLayoutCoordinates();
  191.  
  192. // There is some lag between open soft-keyboard function and when it really appears.
  193. while(currentBottomLocation == layoutBottom && started.get())
  194. {
  195. currentBottomLocation = getLayoutCoordinates();
  196. }
  197.  
  198. if(started.get())
  199. mCallback.onSoftKeyboardChange(true);
  200.  
  201. // When keyboard is opened from EditText, initial bottom location is greater than layoutBottom
  202. // and at some moment equals layoutBottom.
  203. // That broke the previous logic, so I added this new loop to handle this.
  204. while(currentBottomLocation >= layoutBottom && started.get())
  205. {
  206. currentBottomLocation = getLayoutCoordinates();
  207. }
  208.  
  209. // Now Keyboard is shown, keep checking layout dimensions until keyboard is gone
  210. while(currentBottomLocation != layoutBottom && started.get())
  211. {
  212. synchronized(this)
  213. {
  214. try
  215. {
  216. wait(500);
  217. } catch (InterruptedException e)
  218. {
  219. // TODO Auto-generated catch block
  220. e.printStackTrace();
  221. }
  222. }
  223. currentBottomLocation = getLayoutCoordinates();
  224. }
  225.  
  226. if(started.get())
  227. mCallback.onSoftKeyboardChange(false);
  228.  
  229. // if keyboard has been opened clicking and EditText.
  230. if(isKeyboardShow && started.get())
  231. isKeyboardShow = false;
  232.  
  233. // if an EditText is focused, remove its focus (on UI thread)
  234. if(started.get())
  235. mHandler.obtainMessage(CLEAR_FOCUS).sendToTarget();
  236. }
  237. }
  238.  
  239. public void keyboardOpened()
  240. {
  241. synchronized(this)
  242. {
  243. notify();
  244. }
  245. }
  246.  
  247. public void stopThread()
  248. {
  249. synchronized(this)
  250. {
  251. started.set(false);
  252. notify();
  253. }
  254. }
  255.  
  256. }
  257. }
Add Comment
Please, Sign In to add comment