安卓:如何捕获软输入/键盘的长按事件?

12

简短问题版本:如何在Android上捕获软输入/键盘的长按事件?

详细问题版本: 在一个Android应用中,我们有一个多行EditText,并且我们想要实现以下行为: 1. 默认情况下,它显示一个DONE按钮,通过点击它,软输入/键盘将关闭。 2. 如果用户长按DONE按钮,其行为将更改为ENTER按钮,并且EditText中会新建一行。

对于要求#1,我使用了这里的解决方案:https://dev59.com/PW445IYBdhLWcg3wJ298#12570003

对于要求#2,我遇到的阻碍问题是如何捕获长按事件。 我设置了onEditorActionListener,但捕获的事件为空:http://developer.android.com/reference/android/widget/TextView.OnEditorActionListener.html 我查找文档,长按相关的方法是针对硬键盘的:http://developer.android.com/reference/android/view/View.html#onKeyLongPress(int,android.view.KeyEvent),我找不到适用于软输入/键盘的方法。

感谢您关注这个问题。


你尝试过添加doneButton.setOnLongClickListener(new OnLongClickListener() {...});吗? - k3b
2个回答

1
我自己找不到答案,所以我手动编写了解决方案。我在KeyboardView.OnKeyboardActionListeneronPress()onRelease()事件上使用了一个计时器。以下是重要的代码。为了简洁起见,许多TRY/CATCH被省略。当按下键时,我启动一个计时器等待与长按事件相同的时间(ViewConfiguration.getLongPressTimeout()),然后在原始线程上执行on-long-click事件。随后的按键释放和按键按下可以取消任何活动计时器。
public class MyIME
    extends InputMethodService
    implements KeyboardView.OnKeyboardActionListener {
    :
    :
    private Timer timerLongPress  = null;
    :
    :

    @Override
    public void onCreate() {
        super.onCreate();
        :
        :
        timerLongPress = new Timer();
        :
        :
    }

    @Override
    public void onRelease(final int primaryCode) {
        :
        :
        timerLongPress.cancel();
        :
        :
    }

    @Override
    public void onPress(final int primaryCode) {
        :
        :
        timerLongPress.cancel();
        :
        :
        timerLongPress = new Timer();

        timerLongPress.schedule(new TimerTask() {

            @Override
            public void run() {

                try {

                    Handler uiHandler = new Handler(Looper.getMainLooper());

                    Runnable runnable = new Runnable() {

                        @Override
                        public void run() {

                            try {

                                MyIME.this.onKeyLongPress(primaryCode);

                            } catch (Exception e) {
                                Log.e(MyIME.class.getSimpleName(), "uiHandler.run: " + e.getMessage(), e);
                            }

                        }
                    };

                    uiHandler.post(runnable);

                } catch (Exception e) {
                    Log.e(MyIME.class.getSimpleName(), "Timer.run: " + e.getMessage(), e);
                }
            }

        }, ViewConfiguration.getLongPressTimeout());
        :
        :
    }

    public void onKeyLongPress(int keyCode) {
        // Process long-click here
    }

我不太确定你的解决方案是否能按预期工作。根据文档,onPress() 在 onKey() 之前被调用一次,而 onRelease() 在 onKey() 之后被调用。这意味着无论如何都会执行 onKey()。如果实施了你的解决方案,则在长按时,键的正常行为和长按行为都将被执行。 - flide
我能想象到的另一个问题是:“我在哪里设置并如何检索长按键代码?”这将会特别麻烦,因为XML中的结构不提供这样的情况。有任何评论吗? - flide
这似乎有效!唯一的问题是它不会取消短按键所执行的操作,该操作在松开键时发送。通过在覆盖KeyboardView的类中返回true来解决了这个问题。 - Matthew Morrone

-1
创建一个自定义的键盘视图类,通过扩展KeyboardView类。覆盖onLongPress()方法。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接