Why is the android KeyboardView.OnKeyboardActionListener.onRelease () called after every repetition of keywords?

According to the KeyboardView.OnKeyboardActionListener.onRelease() SDK "For duplicate keys, this is called only once." However, if I set isRepeatable to true for the key “a” using the Android Softkeyboard example and the onPress() , onKey() and onRelease() log calls, I get the repetition as expected, but I am observing the following log for one click sequence / repeat / release:

 I/SoftKeyboard(31467): onPress: 97 I/SoftKeyboard(31467): onKey: 97 I/SoftKeyboard(31467): onRelease: 97 I/SoftKeyboard(31467): onKey: 97 I/SoftKeyboard(31467): onRelease: 97 I/SoftKeyboard(31467): onKey: 97 I/SoftKeyboard(31467): onRelease: 97 I/SoftKeyboard(31467): onKey: 97 I/SoftKeyboard(31467): onRelease: 97 I/SoftKeyboard(31467): onKey: 97 I/SoftKeyboard(31467): onRelease: 97 

How can I pinpoint when a touch device was released? Thanks D.

EDIT (Edit by Paul Boddington 07/30/2015)

Although I am not an OP, I would like to include a complete example showing the problem.

MyActivity :

 public class MyActivity extends Activity { private static final String TAG = "MyActivity"; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_my); KeyboardView keyboardView = (KeyboardView) findViewById(R.id.keyboard_view); keyboardView.setKeyboard(new Keyboard(this, R.xml.keyboard)); keyboardView.setOnKeyboardActionListener(new KeyboardView.OnKeyboardActionListener() { @Override public void onPress(int i) { Log.i(TAG, "onPress: " + i); } @Override public void onKey(int i, int[] ints) { Log.i(TAG, "onKey: " + i); } @Override public void onRelease(int i) { Log.i(TAG, "onRelease: " + i); } @Override public void onText(CharSequence charSequence) {} @Override public void swipeLeft() {} @Override public void swipeRight() {} @Override public void swipeDown() {} @Override public void swipeUp() {} }); } } 

keyboard.xml :

 <?xml version="1.0" encoding="utf-8"?> <Keyboard xmlns:android="http://schemas.android.com/apk/res/android"> android:layout_height="wrap_content" android:layout_width="match_parent" > <Row android:keyWidth="25%p" android:keyHeight="60dp"> <Key android:codes="0" android:keyLabel="0" android:isRepeatable="true"/> <Key android:codes="1" android:keyLabel="1" /> <Key android:codes="2" android:keyLabel="2" /> <Key android:codes="3" android:keyLabel="3" /> </Row> </Keyboard> 

activity_my.xml :

 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent"> <android.inputmethodservice.KeyboardView android:id="@+id/keyboard_view" android:layout_width="match_parent" android:layout_height="wrap_content" android:focusable="true" android:focusableInTouchMode="true" /> </LinearLayout> 
+6
source share
2 answers

I could not figure out how to fix KeyboardView to properly emit onRelease() for duplicate keys. So instead, I came up with a workaround that recognizes the release by looking at MotionEvent.ACTION_UP . You only do this for duplicate keys and ignore the onRelease() events for those keys.

 private List<Integer> mRepeatableKeys = new ArrayList<Integer>(); @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); final KeyboardView keyboardView = (KeyboardView) findViewById(R.id.keyboard_view); keyboardView.post(new Runnable() { @Override public void run() { for( Keyboard.Key key : keyboardView.getKeyboard().getKeys() ) { if(key.repeatable) mRepeatableKeys.add(key.codes[0]); } } }); keyboardView.setOnTouchListener(new View.OnTouchListener() { @Override public boolean onTouch(View v, MotionEvent event) { if (event.getAction() == MotionEvent.ACTION_UP) { if(mTrackingRepeatableKey != -1) { Log.i(TAG, "Repeatable key released: " + mTrackingRepeatableKey); mTrackingRepeatableKey = -1; } } return false; } }); keyboardView.setKeyboard(new Keyboard(this, R.xml.keyboard)); keyboardView.setOnKeyboardActionListener(mKeyboardActionListener); } private int mTrackingRepeatableKey = -1; KeyboardView.OnKeyboardActionListener mKeyboardActionListener = new KeyboardView.OnKeyboardActionListener() { @Override public void onPress(int i) { Log.i(TAG, "onPress: " + i); if( mRepeatableKeys.contains(i)) { mTrackingRepeatableKey = i; } } @Override public void onKey(int i, int[] ints) { if( mRepeatableKeys.contains(i)) { Log.i(TAG, "onKey Repeat: " + i); return; } Log.i(TAG, "onKey: " + i); } @Override public void onRelease(int i) { // Ignore release for repeatable keys if( mRepeatableKeys.contains(i)) return; Log.i(TAG, "onRelease: " + i); } @Override public void onText(CharSequence text) { } @Override public void swipeLeft() { } @Override public void swipeRight() { } @Override public void swipeDown() { } @Override public void swipeUp() { } }; 

Tested on Android 5.1. Logs are now read:

 I/MainActivity﹕ onPress: 1 I/MainActivity﹕ onKey Repeat: 1 I/MainActivity﹕ onKey Repeat: 1 I/MainActivity﹕ onKey Repeat: 1 I/MainActivity﹕ onKey Repeat: 1 I/MainActivity﹕ onKey Repeat: 1 I/MainActivity﹕ onKey Repeat: 1 I/MainActivity﹕ onKey Repeat: 1 I/MainActivity﹕ onKey Repeat: 1 I/MainActivity﹕ Repeatable key released: 1 

If you want, you can extend KeyboardView to include all this ugly logic.

+2
source

I didn’t program much on Android, but would it not be easy to check if the key is still pressed inside the onRelease method using the onLongPress method?

 @Override public void onRelease(int i) { if(keyboardView.onLongPress(i){ //do nothing } else{ Log.i(TAG, "onRelease: " + i); } } 

If I am mistaken, this method should return true if your finger is still on the key and false when you stop.

0
source

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


All Articles