OnEditorActionListener在SenseUI键盘上使用相同的eventTime调用两次

时间:2010-11-03 14:06:23

标签: android

在我正在测试的一部手机上(HTC Incredible,Android 2.2,Software 3.21.605.1),我遇到以下行为。

当按下Sense UI键盘上的Enter键时,onEditorAction事件处理程序被调用两次(立即)。

KeyEvent.getEventTime()对于调用事件的两次都是相同的,这使我得以解决这个问题:

protected void onCreate(Bundle savedInstanceState) {
    [...]

    EditText text = (EditText)findViewById(R.id.txtBox);
    text.setOnEditorActionListener(new OnEditorActionListener() {
        private long lastCalled = -1;

        public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
            if ( event.getEventTime() == lastCalled ) {
                return false;
            } else {
                lastCalled = event.getEventTime();
                handleNextButton(v);
                return true;
            }
        }
    });

    [...]
}

EditText定义为:

<EditText 
    android:layout_width="150sp" 
    android:layout_height="wrap_content"
    android:id="@+id/txtBox" 
    android:imeOptions="actionNext"
    android:capitalize="characters" 
    android:singleLine="true"
    android:inputType="textVisiblePassword|textCapCharacters|textNoSuggestions"
    android:autoText="false" 
    android:editable="true" 
    android:maxLength="6"
/>

在我测试过的所有其他设备上,操作按钮被正确标记为“下一步”,并且该事件仅在按下该按钮时被调用一次。

这是Sense UI键盘中的错误,还是我做错了什么?

感谢您的帮助。


更新 - 由于给出的答案,我已经确定以下作为我的支票。这在我可用于测试的两部手机上都能正常工作(Sense UI和Cyanogenmod CM7)

            if (event != null && event.getAction() != KeyEvent.ACTION_DOWN) {
                return false;
            }

            if ( actionId != EditorInfo.IME_ACTION_NEXT && actionId != EditorInfo.IME_NULL ) {
                return false;
            }

6 个答案:

答案 0 :(得分:28)

正如米奇所说,你必须检查事件动作:

public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
    if (event.getAction() != KeyEvent.ACTION_DOWN)
        return false;

    // do your stuff

    return true;
}

此代码段适用于Sense UI和模拟器。

答案 1 :(得分:3)

(EditText) passwordView = (EditText) findViewById(R.id.password);
passwordView.setImeOptions(EditorInfo.IME_ACTION_DONE);
    passwordView.setOnEditorActionListener(new OnEditorActionListener()
        {
            @Override
            public boolean onEditorAction(TextView v, int actionId, KeyEvent event)
            {
                String input;
                if(actionId == EditorInfo.IME_ACTION_DONE)
                {
                   input= v.getText().toString();
                    Toast toast= Toast.makeText(LogIn.this,input,
                            Toast.LENGTH_LONG);
                    toast.setGravity(Gravity.CENTER, 0, 0);
                    toast.show();
                    return true;
                }
                return false;
            }
        });

答案 2 :(得分:2)

我认为如果你返回true,则意味着你对其余的事件感兴趣,直到它到达IME_ACTION_DONE。因此,如果您返回false,则表示您对事件不感兴趣,并且其他视图将有机会处理它。由于您只有1个视图,我建议您忽略actionId检查并且每次都返回false。

etMovieName = (EditText) view.findViewById(R.id.et_movie_name);
etMovieName.setOnEditorActionListener(new TextView.OnEditorActionListener() {
    @Override
    public boolean onEditorAction(TextView tv, int actionId, KeyEvent event) {
        System.out.println("actionId= "+ actionId);
        performSearch();
        return false;
    }
});

其他情况是,如果您有重叠的视图或兄弟视图,那么您可以使用actionId传递信息。在这种情况下,返回true将允许您将信息传递给另一个视图。如果你真的对event / actionId感兴趣(例如,如果你有另一个兄弟视图),那么你可以这样做:

etMovieName = (EditText) view.findViewById(R.id.et_movie_name);

etMovieName.setImeOptions(EditorInfo.IME_ACTION_DONE);
etMovieName.setSingleLine();

etMovieName.setOnEditorActionListener(new TextView.OnEditorActionListener() {
    @Override
    public boolean onEditorAction(TextView tv, int actionId, KeyEvent event) {
        System.out.println("actionId= "+ actionId);
        return performSearch();      }
});

请注意,添加后,actionId值已更改为6:

etMovieName.setImeOptions(EditorInfo.IME_ACTION_DONE);
etMovieName.setSingleLine();

答案 3 :(得分:1)

除了@Gubbel的回答之外,我认为听ACTION_UP而不是ACTION_DOWN会更好,因为用户实际上可以用手指轻触输入键(ACTION_DOWN)但是然后犹豫并把它拿到其他地方。

通常我们只想在用户从输入键释放手指时触发事件。

所以代码将是这样的:

        @Override
        public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
            boolean handled = false;
            if (event.getAction() == KeyEvent.ACTION_DOWN) return true;
            if ((actionId == EditorInfo.IME_ACTION_DONE || actionId == EditorInfo.IME_NULL)
                    && event.getAction() == KeyEvent.ACTION_UP) {
                //Do your stuff here
                handled = true;
            }
            return handled;
        }

答案 4 :(得分:0)

而不是发送ime动作并将null作为事件发送,它会发送触摸事件,因此如果您没有得到正确的操作,您可以检查事件是否为action_up或action_down

答案 5 :(得分:0)

返回true; 在处理你的案件后,它将不再被召唤

public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {

                if (actionId == EditorInfo.IME_NULL)
                {
                    Log.i("here","Add product ");
                    return true;  //this does the trick
                }
                return false;
            }