Guest User

Untitled

a guest
May 27th, 2015
226
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 5.72 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. public void onSoftKeyboardHide();
  77. public void onSoftKeyboardShow();
  78. }
  79.  
  80. private int getLayoutCoordinates()
  81. {
  82. layout.getLocationOnScreen(coords);
  83. return coords[1] + layout.getHeight();
  84. }
  85.  
  86. private void keyboardHideByDefault()
  87. {
  88. layout.setFocusable(true);
  89. layout.setFocusableInTouchMode(true);
  90. }
  91.  
  92. /*
  93. * InitEditTexts now handles EditTexts in nested views
  94. * Thanks to Francesco Verheye (verheye.francesco@gmail.com)
  95. */
  96. private void initEditTexts(ViewGroup viewgroup)
  97. {
  98. if(editTextList == null)
  99. editTextList = new ArrayList<EditText>();
  100.  
  101. int childCount = viewgroup.getChildCount();
  102. for(int i=0; i<= childCount-1;i++)
  103. {
  104. View v = viewgroup.getChildAt(i);
  105.  
  106. if(v instanceof ViewGroup)
  107. {
  108. initEditTexts((ViewGroup) v);
  109. }
  110.  
  111. if(v instanceof EditText)
  112. {
  113. EditText editText = (EditText) v;
  114. editText.setOnFocusChangeListener(this);
  115. editText.setCursorVisible(true);
  116. editTextList.add(editText);
  117. }
  118. }
  119. }
  120.  
  121. /*
  122. * OnFocusChange does update tempView correctly now when keyboard is still shown
  123. * Thanks to Israel Dominguez (dominguez.israel@gmail.com)
  124. */
  125. @Override
  126. public void onFocusChange(View v, boolean hasFocus)
  127. {
  128. if(hasFocus)
  129. {
  130. tempView = v;
  131. if(!isKeyboardShow)
  132. {
  133. layoutBottom = getLayoutCoordinates();
  134. softKeyboardThread.keyboardOpened();
  135. isKeyboardShow = true;
  136. }
  137. }
  138. }
  139.  
  140. // This handler will clear focus of selected EditText
  141. private final Handler mHandler = new Handler()
  142. {
  143. @Override
  144. public void handleMessage(Message m)
  145. {
  146. switch(m.what)
  147. {
  148. case CLEAR_FOCUS:
  149. if(tempView != null)
  150. {
  151. tempView.clearFocus();
  152. tempView = null;
  153. }
  154. break;
  155. }
  156. }
  157. };
  158.  
  159. private class SoftKeyboardChangesThread extends Thread
  160. {
  161. private AtomicBoolean started;
  162. private SoftKeyboardChanged mCallback;
  163.  
  164. public SoftKeyboardChangesThread()
  165. {
  166. started = new AtomicBoolean(true);
  167. }
  168.  
  169. public void setCallback(SoftKeyboardChanged mCallback)
  170. {
  171. this.mCallback = mCallback;
  172. }
  173.  
  174. @Override
  175. public void run()
  176. {
  177. while(started.get())
  178. {
  179. // Wait until keyboard is requested to open
  180. synchronized(this)
  181. {
  182. try
  183. {
  184. wait();
  185. } catch (InterruptedException e)
  186. {
  187. e.printStackTrace();
  188. }
  189. }
  190.  
  191. int currentBottomLocation = getLayoutCoordinates();
  192.  
  193. // There is some lag between open soft-keyboard function and when it really appears.
  194. while(currentBottomLocation == layoutBottom && started.get())
  195. {
  196. currentBottomLocation = getLayoutCoordinates();
  197. }
  198.  
  199. if(started.get())
  200. mCallback.onSoftKeyboardShow();
  201.  
  202. // When keyboard is opened from EditText, initial bottom location is greater than layoutBottom
  203. // and at some moment equals layoutBottom.
  204. // That broke the previous logic, so I added this new loop to handle this.
  205. while(currentBottomLocation >= layoutBottom && started.get())
  206. {
  207. currentBottomLocation = getLayoutCoordinates();
  208. }
  209.  
  210. // Now Keyboard is shown, keep checking layout dimensions until keyboard is gone
  211. while(currentBottomLocation != layoutBottom && started.get())
  212. {
  213. synchronized(this)
  214. {
  215. try
  216. {
  217. wait(500);
  218. } catch (InterruptedException e)
  219. {
  220. // TODO Auto-generated catch block
  221. e.printStackTrace();
  222. }
  223. }
  224. currentBottomLocation = getLayoutCoordinates();
  225. }
  226.  
  227. if(started.get())
  228. mCallback.onSoftKeyboardHide();
  229.  
  230. // if keyboard has been opened clicking and EditText.
  231. if(isKeyboardShow && started.get())
  232. isKeyboardShow = false;
  233.  
  234. // if an EditText is focused, remove its focus (on UI thread)
  235. if(started.get())
  236. mHandler.obtainMessage(CLEAR_FOCUS).sendToTarget();
  237. }
  238. }
  239.  
  240. public void keyboardOpened()
  241. {
  242. synchronized(this)
  243. {
  244. notify();
  245. }
  246. }
  247.  
  248. public void stopThread()
  249. {
  250. synchronized(this)
  251. {
  252. started.set(false);
  253. notify();
  254. }
  255. }
  256.  
  257. }
  258. }
Add Comment
Please, Sign In to add comment