Gesturin - Android рдХреЗ рд▓рд┐рдП рдЗрд╢рд╛рд░рд╛ рдЗрдирдкреБрдЯ


рдЗрд╕ рдкреЛрд╕реНрдЯ рдореЗрдВ рдореИрдВ рдЖрдкрдХреЛ рдмрддрд╛рдКрдВрдЧрд╛ рдХрд┐ рдПрдВрдбреНрд░реЙрдЗрдб рдХреЗ рд▓рд┐рдП рдПрдХ рдЬреЗрд╕реНрдЪрд░ рдЗрдирдкреБрдЯ рд╡рд┐рдзрд┐ рдХреИрд╕реЗ рдмрдирд╛рдИ рдЬрд╛рддреА рд╣реИред рдЗрд╕ рдЗрдирдкреБрдЯ рдкрджреНрдзрддрд┐ рдХреЛ рд▓рд┐рдЦрд╛рд╡рдЯ рдХреЗ рд╕рдорд╛рди рдмрдирд╛рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ, рд▓реЗрдХрд┐рди рдПрдХ рд╕реАрдорд╛ рд╣реИ - рдЖрдкрдХреЛ рдЕрдкрдиреА рдЙрдВрдЧрд▓реА рдЙрдард╛рдП рдмрд┐рдирд╛ рдПрдХ рдЕрдХреНрд╖рд░ (рд╕рдВрдЦреНрдпрд╛, рд╢рдмреНрдж) рдЦреАрдВрдЪрдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИред рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдореЗрдВ рдПрдХ рдЗрдирдкреБрдЯ рд╡рд┐рдзрд┐ рдФрд░ рдЗрд╢рд╛рд░реЛрдВ рдХреЛ рд╕реНрдерд╛рдкрд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдПрдХ рдЙрдкрдпреЛрдЧрд┐рддрд╛ рд╢рд╛рдорд┐рд▓ рд╣реИ, рдЬреЛ рдХрд┐ рдПрдВрдбреНрд░реЙрдЗрдб рдПрд╕рдбреАрдХреЗ рдХреЗ рд▓рд┐рдП рдЙрджрд╛рд╣рд░рдгреЛрдВ рд╕реЗ рдПрдХ рдкреБрдирд░реНрдирд┐рд░реНрдорд┐рдд "рдЬреЗрд╕реНрдЪрд░ рдмрд┐рд▓реНрдбрд░" рд╣реИред


рдПрдХ рдХреАрдмреЛрд░реНрдб рдмрдирд╛рдирд╛


рдХреАрдмреЛрд░реНрдб рдХреНрд▓рд╛рд╕ рдмрдирд╛рдХрд░ рд╢реБрд░реВ рдХрд░рддреЗ рд╣реИрдВред рд╕рднреА рдЗрдирдкреБрдЯ рд╡рд┐рдзрд┐рдпрд╛рдБ InputMethodService рдкрд░ рдЖрдзрд╛рд░рд┐рдд рд╣реИрдВ, рдФрд░ рдЬреЗрд╕реНрдЪрд░ рдкрд╣рдЪрд╛рди рдХреЗ рд▓рд┐рдП, рд╣рдордиреЗ рдЗрд╕рдореЗрдВ OnGesturePerformedListener рдХреЛ рд╢рд╛рдорд┐рд▓ рдХрд┐рдпрд╛ рд╣реИред рдорд╛рдиреНрдпрддрд╛ рд╕рдорд╕реНрдпрд╛рдУрдВ рд╕реЗ рдмрдЪрдиреЗ рдХреЗ рд▓рд┐рдП, рдкреНрд░рддреНрдпреЗрдХ рднрд╛рд╖рд╛ рдХреА рдПрдХ рдЕрд▓рдЧ рдлрд╝рд╛рдЗрд▓ рд╣реЛрдЧреАред рдРрд╕рд╛ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рд╡рд░реНрдЧ рдореЗрдВ рджреЛ рдЧреБрдг рдЬреЛрдбрд╝реЗрдВ: рднрд╛рд╖рд╛рдУрдВ рдХрд╛ рдорд╛рдирдЪрд┐рддреНрд░ рдФрд░ рд╡рд░реНрддрдорд╛рди рднрд╛рд╖рд╛ рдХрд╛ рдирд╛рдоред
// HashMap< ,  > private HashMap<String, GestureLibrary> mGestureLibMap; //   private String mCurrentGestureLib = null; 

рд▓реЛрдб рднрд╛рд╖рд╛рдПрдБ рд▓реЛрдбрд▓рдВрдЧреЗрдЬ рд╡рд┐рдзрд┐ рд╣реЛрдВрдЧреА, рдЬреЛ рдПрдкреНрд▓рд┐рдХреЗрд╢рди рдлрд╝рд╛рдЗрд▓ рдирд┐рд░реНрджреЗрд╢рд┐рдХрд╛ рдХреЛ рд╕реНрдХреИрди рдХрд░реЗрдЧреА рдФрд░ рд╕рднреА рд╕рд╛рдордЧреНрд░рд┐рдпреЛрдВ рдХреЛ рднрд╛рд╖рд╛рдУрдВ рдХреЗ рд░реВрдк рдореЗрдВ рд▓реЛрдб рдХрд░реЗрдЧреАред
 private void loadLanguages() { //   "" File[] files = getFilesDir().listFiles(); mGestureLibMap = new HashMap<String, GestureLibrary>(); //  "" for(int i = 0; i < files.length; i++) { GestureLibrary gestureLib = GestureLibraries.fromFile(files[i]); if (!gestureLib.load()) { Toast.makeText(this, "Can't load gestures " + files[i].getName(), Toast.LENGTH_LONG).show(); continue; } //     mGestureLibMap.put(files[i].getName(), gestureLib); } if(mCurrentGestureLib == null || !mGestureLibMap.containsKey(mCurrentGestureLib)) { //       mCurrentGestureLib = mGestureLibMap.keySet().toArray(new String[0])[0]; if(mGestureLibMap.containsKey(mCurrentGestureLib.toLowerCase())) mCurrentGestureLib = mCurrentGestureLib.toLowerCase(); } } 

loadLanguages тАЛтАЛрдХреЛ onStartInputView рдореЗрдердб рдореЗрдВ рдХрд╣рд╛ рдЬрд╛рдПрдЧрд╛, рдЬрд┐рд╕реЗ рд╣рд░ рдмрд╛рд░ рдХреАрдмреЛрд░реНрдб рдХрд╣рд╛ рдЬрд╛рддрд╛ рд╣реИред рдпрд╣ рд╕рдорд╛рдзрд╛рди рд╕рдВрднрд╡рддрдГ рдмрдбрд╝реА рд╕рдВрдЦреНрдпрд╛ рдореЗрдВ рднрд╛рд╖рд╛рдУрдВ рдХреЗ рд╕рд╛рде рдмреНрд░реЗрдХ рдХрд╛ рдХрд╛рд░рдг рдмрдиреЗрдЧрд╛, рд▓реЗрдХрд┐рди рдЗрд╕ рддрд░рд╣ рд╣рдореЗрд╢рд╛ "рддрд╛рдЬрд╝рд╛" рдЗрд╢рд╛рд░реЗ рд╣реЛрдВрдЧреЗред рдпрд╣ рдЕрдВрддрд┐рдо рдЬреЗрд╕реНрдЪрд░ рдЕрдкрдбреЗрдЯ рдпрд╛ рд╕реНрдерд┐рд░ рд╕рдВрдкрддреНрддрд┐ рдХреА рдлрд╛рдЗрд▓ рдХреЗ рд╕рд╛рде рдореБрд╢реНрдХрд┐рд▓ рд╣реЛ рд╕рдХрддрд╛ рдерд╛, рд▓реЗрдХрд┐рди рдореИрдВрдиреЗ рддрдм рд╕реЗ рдЯреНрд░рд┐рдХ рдХрд░рдирд╛ рд╢реБрд░реВ рдирд╣реАрдВ рдХрд┐рдпрд╛ рдерд╛ рдЬрдм рдореИрдВрдиреЗ рдорд╛рдирдХ рд╕реЗрдЯ (рдПрди, рдЖрд░рдпреВ, 09) рдХреЗ рд╕рд╛рде рдХрд┐рд╕реА рднреА рдмреНрд░реЗрдХ рдХреЛ рдиреЛрдЯрд┐рд╕ рдирд╣реАрдВ рдХрд┐рдпрд╛ рдерд╛ред

рдЗрд╢рд╛рд░реЛрдВ рдХреЛ OnGesturePerformed рдореЗрдердб рдореЗрдВ рдкрд╣рдЪрд╛рдирд╛ рдЬрд╛рддрд╛ рд╣реИ (рдЗрд╢рд╛рд░реЛрдВ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдЕрдзрд┐рдХ рдЬрд╛рдирдХрд╛рд░реА рдпрд╣рд╛рдБ рдорд┐рд▓ рд╕рдХрддреА рд╣реИ )ред рдпрджрд┐ рдЗрд╢рд╛рд░рд╛ рдХрд╛ рдирд╛рдо "@@" рд╕реЗ рд╢реБрд░реВ рд╣реЛрддрд╛ рд╣реИ, рддреЛ рд╣рдо рдорд╛рдирддреЗ рд╣реИрдВ рдХрд┐ рдпрд╣ рдХреБрдВрдЬреАрдХреЛрдб рджреНрд╡рд╛рд░рд╛ рдкреАрдЫрд╛ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рдЬрд┐рд╕реЗ рд╣рдо рдЖрд╡реЗрджрди рдкрд░ рднреЗрдЬ рджреЗрдВрдЧреЗред рдпрджрд┐ рдпрд╣ рдХреБрдЫ рдФрд░ рдХреЗ рд╕рд╛рде рд╢реБрд░реВ рд╣реЛрддрд╛ рд╣реИ, рддреЛ рд╣рдо рдЗрд╕реЗ рдкрд╛рда рдХреЗ рд░реВрдк рдореЗрдВ рднреЗрдЬ рджреЗрдВрдЧреЗред рд╡рд┐рдзрд┐ рд╕реНрд╡рдпрдВ рдЗрд╕ рддрд░рд╣ рджрд┐рдЦрддреА рд╣реИ:
 public void onGesturePerformed(GestureOverlayView overlay, Gesture gesture) { //   ArrayList<Prediction> predictions = mGestureLibMap.get(mCurrentGestureLib).recognize(gesture); if (predictions.size() > 0) { //     Prediction prediction = predictions.get(0); if(prediction.name.startsWith("@@")) { //     @@,        try { keyDownUp(Integer.valueOf(prediction.name.substring(2))); } catch(NumberFormatException e) { Log.w("GestureKeyboard", "NumberFormatException: " + e.getLocalizedMessage()); } } else { //      getCurrentInputConnection().commitText(editString(prediction.name), prediction.name.length()); } } } 

рдЗрд╕ рд╡рд┐рдзрд┐ рдореЗрдВ, рдЖрдк рдПрдХ рдЕрдЬреНрдЮрд╛рдд editString рд╡рд┐рдзрд┐ рджреЗрдЦ рд╕рдХрддреЗ рд╣реИрдВред рдпрд╣ рд╡рд┐рдзрд┐ "рдЕрдкрд░" рдФрд░ "рд▓реЛрдЕрд░" рдмрдЯрди рдХреА рд╕реНрдерд┐рддрд┐ рдХреЗ рдЖрдзрд╛рд░ рдкрд░ рдорд╛рдорд▓реЗ рдХреЛ рдмрджрд▓ рджреЗрддреА рд╣реИред
 private String editString(String in) { //   lower,    LowerCase if(mLowerLock.isChecked()) return in.toLowerCase(); //  upper,   UpperCase if(mUpperLock.isChecked()) return in.toUpperCase(); //    return in; } 

рдФрд░ keyDownUp рд╡рд┐рдзрд┐ рджреЛ рдШрдЯрдирд╛рдУрдВ рдХреЛ рдЕрдиреБрдкреНрд░рдпреЛрдЧ рдореЗрдВ рднреЗрдЬрддреА рд╣реИ - рдХреАрдбрд╛рдЙрди рдФрд░ рдХреАрдпреВрдкреАред рдпрд╣ рд╕реЙрдлреНрдЯрдХреЗрдпрдмреЛрд░реНрдб рдЙрджрд╛рд╣рд░рдг рд╕реЗ рд▓рд┐рдпрд╛ рдЧрдпрд╛ рдерд╛ рдФрд░ рдЗрд╕ рддрд░рд╣ рджрд┐рдЦрддрд╛ рд╣реИ:
 private void keyDownUp(int keyEventCode) { //   keyDown  keyUp getCurrentInputConnection().sendKeyEvent(new KeyEvent(KeyEvent.ACTION_DOWN, keyEventCode)); getCurrentInputConnection().sendKeyEvent(new KeyEvent(KeyEvent.ACTION_UP, keyEventCode)); } 

рд╣рдордиреЗ рд╡рд┐рднрд┐рдиреНрди рднрд╛рд╖рд╛рдУрдВ рдХреЛ рдбрд╛рдЙрдирд▓реЛрдб рдХрд┐рдпрд╛, рдЬрд┐рд╕рдХрд╛ рдЕрд░реНрде рд╣реИ рдХрд┐ рдЙрдиреНрд╣реЗрдВ рдмрджрд▓рд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИред рд╡реЗ рджреЛ рддрд░реАрдХреЛрдВ рдХреЗ рдПрдХ рд╕рдореВрд╣ рдХреЗ рд╕рд╛рде рдмрджрд▓рддреЗ рд╣реИрдВ - onLangClick рдФрд░ setCurrentLanguageред OnLangClick рдмрдЯрди рдкрд░ рдХреНрд▓рд┐рдХ рдХрд░рдиреЗ рдкрд░, рд╣рдо рд╡рд░реНрддрдорд╛рди рдПрдХ рдХреЗ рдмрдЧрд▓ рдореЗрдВ рднрд╛рд╖рд╛рдУрдВ рдХреА рд╕реВрдЪреА рдореЗрдВ рджреЗрдЦрддреЗ рд╣реИрдВ, рдпрд╛ (рдпрджрд┐ рдХреЛрдИ рдирд╣реАрдВ рд╣реИ) рддреЛ рднрд╛рд╖рд╛ рдХреЛ рдкрд╣рд▓реЗ рдПрдХ рдореЗрдВ рдмрджрд▓ рджреЗрдВред рднрд╛рд╖рд╛ рдмрджрд▓рддреЗ рд╕рдордп, "рдХреИрдкреНрд╕ рд▓реЙрдХ" рдмрдЯрди рдХреА рд╕реНрдерд┐рддрд┐ рдХреЛ рднреА рдзреНрдпрд╛рди рдореЗрдВ рд░рдЦрд╛ рдЬрд╛рддрд╛ рд╣реИред
 public void onLangClick(View v) { //      //    String gestureNames[] = mGestureLibMap.keySet().toArray(new String[0]); boolean next = false; for(int i = 0; i < gestureNames.length; i++) { if(next) { //      if(!mCurrentGestureLib.toLowerCase().equals(gestureNames[i].toLowerCase())) { //        setCurrentLanguage(gestureNames, i); next = false; break; } continue; } if(mCurrentGestureLib.toLowerCase().equals(gestureNames[i].toLowerCase())) { //      next = true; } } if(next) setCurrentLanguage(gestureNames, 0); //   mLangSwither.setText(mCurrentGestureLib); } private void setCurrentLanguage(String gestureNames[], int index) { mCurrentGestureLib = gestureNames[index]; //      LowerCase,    if(mGestureLibMap.containsKey(gestureNames[index].toLowerCase())) { mCurrentGestureLib = gestureNames[index].toLowerCase(); } //   ,      UpperCase     if(mCapsLock.isChecked() && mGestureLibMap.containsKey(gestureNames[index].toUpperCase())) { mCurrentGestureLib = gestureNames[index].toUpperCase(); } } 

рдорд╛рдорд▓реЗ рдХреЛ рдмрджрд▓рдиреЗ рдХреЗ рд▓рд┐рдП, рддреАрди рдмрдЯрди рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ: рдКрдкрд░реА, рдирд┐рдЪрд▓рд╛, рдХреИрдкреНрд╕ред рдХреБрдЫ рджрд┐рд▓рдЪрд╕реНрдк рдХреЗрд╡рд▓ рдЯреЛрдкреА рд╣реИред рднрд╛рд╖рд╛ рджреЛ рд░рдЬрд┐рд╕реНрдЯрд░реЛрдВ рдореЗрдВ рд╣реЛ рд╕рдХрддреА рд╣реИред рд░рдЬрд┐рд╕реНрдЯрд░ рднрд╛рд╖рд╛ рдХреЗ рдирд╛рдо рд╕реЗ рд▓рд┐рдЦрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ (рдЙрджрд╛рд╣рд░рдг: en рдФрд░ EN)ред рд▓реЗрдХрд┐рди рдХреИрдкреНрд╕ рдмрдЯрди рдЗрди рд░рдЬрд┐рд╕реНрдЯрд░реЛрдВ рдХреЛ рд╕реНрд╡рд┐рдЪ рдХрд░рддрд╛ рд╣реИ рдпрд╛, рдпрджрд┐ рд╡реЗ рдЕрдиреБрдкрд╕реНрдерд┐рдд рд╣реИрдВ, рддреЛ рдКрдкрд░реА рдФрд░ рдирд┐рдЪрд▓реЗ рдмрдЯрди рдХреА рд╕реНрдерд┐рддрд┐ рдХреЛ рдмрджрд▓ рджреЗрддрд╛ рд╣реИред
 if(isChecked) { mLowerLock.setChecked(false); if(mGestureLibMap.containsKey(mCurrentGestureLib.toUpperCase())) { //    UpperCase mUpperLock.setChecked(false); mCurrentGestureLib = mCurrentGestureLib.toUpperCase(); } else { //     UpperCase,   UpperLock mUpperLock.setChecked(true); } } else { mUpperLock.setChecked(false); if(mGestureLibMap.containsKey(mCurrentGestureLib.toLowerCase())) { //    LowerCase mLowerLock.setChecked(false); mCurrentGestureLib = mCurrentGestureLib.toLowerCase(); } else { //   LowerLock mLowerLock.setChecked(true); } } //   mLangSwither.setText(mCurrentGestureLib); 

UI рдХреЛ рдереЛрдбрд╝рд╛ рдЕрд▓рдВрдХреГрдд рдХрд░рдиреЗ рдХреЗ рдмрд╛рдж, рдпрд╣ рд╕реНрдХреНрд░реАрдирд╢реЙрдЯ рдореЗрдВ рджрд┐рдЦрд╛рдпрд╛ рдЧрдпрд╛ рд╣реИред
рдЗрдирдкреБрдЯ рд╡рд┐рдзрд┐ рд╡рд░реНрдЧ рддреИрдпрд╛рд░ рд╣реИ, рдЕрдм рдЖрдкрдХреЛ AndroidManifest.xml рдореЗрдВ рдХреБрдЫ рдЗрд╕ рддрд░рд╣ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ:

 <service android:name="GestureKeyboard" android:permission="android.permission.BIND_INPUT_METHOD"> <intent-filter> <action android:name="android.view.InputMethod"/> </intent-filter> <meta-data android:name="android.view.im" android:resource="@xml/method"/> </service> 

UI рдХреЛ рдереЛрдбрд╝рд╛ рдЕрд▓рдВрдХреГрдд рдХрд░рдиреЗ рдХреЗ рдмрд╛рдж, рдпрд╣ рд╕реНрдХреНрд░реАрдирд╢реЙрдЯ рдореЗрдВ рджрд┐рдЦрд╛рдпрд╛ рдЧрдпрд╛ рд╣реИред

рдореИрдВ рдЖрдкрдХреЛ рд╢рдмреНрджреЛрдВ рдореЗрдВ рд╕реЗрдЯрд┐рдВрдЧреНрд╕ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдмрддрд╛рдКрдВрдЧрд╛ред рд╢реБрд░реБрдЖрдд рд╕реЗ, рдореИрдВрдиреЗ рдПрдВрдбреНрд░реЙрдЗрдб рдПрд╕рдбреАрдХреЗ рд╕реЗ рдЬреЗрд╕реНрдЪрд░ рдмрд┐рд▓реНрдбрд░ рдХреЗ рд╕реНрд░реЛрддреЛрдВ рдХреЛ рд▓рд┐рдпрд╛, рдФрд░ рдЕрдкрдиреЗ рдкреНрд░реЛрдЬреЗрдХреНрдЯ рдореЗрдВ рдЖрд╡рд╢реНрдпрдХ рд╕реНрд░реЛрддреЛрдВ рдФрд░ рд╕рдВрд╕рд╛рдзрдиреЛрдВ рдХреА рдирдХрд▓ рдХреАред рд╕рдВрд╕рд╛рдзрди рдФрд░ рд╕реНрд░реЛрдд "рд╕реБрдкрд░рдлреНрд▓рд╕" рд╕реЗ рд╕рд╛рдл рд╣реЛ рдЧрдПред рдЕрдЧрд▓рд╛, рдореИрдВрдиреЗ GestureBuilderActivity рдХреНрд▓рд╛рд╕ рдХреЛ рдмрджрд▓ рджрд┐рдпрд╛ рддрд╛рдХрд┐ рдпрд╣ рдирд┐рд░реНрджрд┐рд╖реНрдЯ рдЗрд╢рд╛рд░реЛрдВ рдХреЛ рдЦреЛрд▓реЗ (рдФрд░ / sdcard / рдЬреЗрд╕реНрдЪрд░) рдирд╣реАрдВред рдФрд░ рдЬреЛрдбрд╝рдиреЗ, рд╣рдЯрд╛рдиреЗ рдФрд░ рдирд╛рдо рдмрджрд▓рдиреЗ рдХреЗ рдХрд╛рд░реНрдпреЛрдВ рдХреЗ рд╕рд╛рде рднрд╛рд╖рд╛рдУрдВ рдХреА рдПрдХ рд╕реВрдЪреА рдмрдирд╛рдИред

рдкрд░рд┐рдгрд╛рдо


рдкрд░рд┐рдгрд╛рдорд╕реНрд╡рд░реВрдк "рдХреАрдмреЛрд░реНрдб" рдХреЛ рдореЗрд░реА рд▓рд┐рдЦрд╛рд╡рдЯ рджреНрд╡рд╛рд░рд╛ рдмреБрд░реА рддрд░рд╣ рд╕реЗ рдкрд╣рдЪрд╛рдирд╛ рдирд╣реАрдВ рдЧрдпрд╛ рд╣реИ, рд▓реЗрдХрд┐рди рдореИрдВрдиреЗ рдЗрд╕рдХрд╛ рдЙрдкрдпреЛрдЧ рдирд┐рд░рдВрддрд░ рдЖрдзрд╛рд░ рдкрд░ рдирд╣реАрдВ рдХрд┐рдпрд╛ - рдХреБрдВрдЬреА рдореЗрд░реЗ рд▓рд┐рдП рдЕрдзрд┐рдХ рд╕реБрд╡рд┐рдзрд╛рдЬрдирдХ рд╣реИред рд╕рднреА рд╕реНрд░реЛрддреЛрдВ рдХреЛ googlecode.com рдкрд░ рджреЗрдЦрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИред рдЖрдИрдмрд┐рдб рдбрд╛рдЙрдирд▓реЛрдб apk рдмрд┐рд▓реНрдЯ-рдЗрди рдЕрдВрдЧреНрд░реЗрдЬреА, рд░реВрд╕реА рдФрд░ рдбрд┐рдЬрд┐рдЯрд▓ (рдореЗрд░реА рд▓рд┐рдЦрд╛рд╡рдЯ рдХреЗ рд▓рд┐рдП) рдХреЗ рд╕рд╛рдеред

Source: https://habr.com/ru/post/In121153/


All Articles