OnEditorActionListener chamado duas vezes com o mesmo eventoTime no keyboard SenseUI

Em apenas um telefone em que estou testando (HTC Incredible, Android 2.2, Softwaire 3.21.605.1), estou tendo o seguinte comportamento.

O manipulador de events onEditorAction está sendo chamado duas vezes (imediatamente) quando a tecla Enter no keyboard Sense UI é pressionada.

O KeyEvent.getEventTime () é o mesmo paira as duas vezes que o evento é chamado, levando-me a este trabalho:

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; } } }); [...] } 

O EditText é definido como:

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

Em todos os outros dispositivos em que testei, o button de ação é rotulado corretamente como "Próximo" e o evento é chamado somente de uma única vez quando esse button é pressionado.

Isso é um erro no keyboard Sense UI, ou estou fazendo algo incorretamente?

Obrigado por qualquer ajuda.


Atualizado – graças às respostas dadas, estabeleci o seguinte como meus cheques. Isso funciona bem em ambos os telefones que tenho disponíveis paira testair (Sense UI e Cyanogenmod CM7)

  if (event != null && event.getAction() != KeyEvent.ACTION_DOWN) { return false; } if ( actionId != EditorInfo.IME_ACTION_NEXT && actionId != EditorInfo.IME_NULL ) { return false; } retornair falso;  if (event != null && event.getAction() != KeyEvent.ACTION_DOWN) { return false; } if ( actionId != EditorInfo.IME_ACTION_NEXT && actionId != EditorInfo.IME_NULL ) { return false; } }  if (event != null && event.getAction() != KeyEvent.ACTION_DOWN) { return false; } if ( actionId != EditorInfo.IME_ACTION_NEXT && actionId != EditorInfo.IME_NULL ) { return false; } retornair falso;  if (event != null && event.getAction() != KeyEvent.ACTION_DOWN) { return false; } if ( actionId != EditorInfo.IME_ACTION_NEXT && actionId != EditorInfo.IME_NULL ) { return false; } 

5 Solutions collect form web for “OnEditorActionListener chamado duas vezes com o mesmo eventoTime no keyboard SenseUI”

Como disse a Mitch, você deve viewificair a ação do evento:

 public boolean onEditorAction(TextView v, int actionId, KeyEvent event) { if (event.getAction() != KeyEvent.ACTION_DOWN) return false; // do your stuff return true; } retornair falso; public boolean onEditorAction(TextView v, int actionId, KeyEvent event) { if (event.getAction() != KeyEvent.ACTION_DOWN) return false; // do your stuff return true; } retornair viewdadeiro; public boolean onEditorAction(TextView v, int actionId, KeyEvent event) { if (event.getAction() != KeyEvent.ACTION_DOWN) return false; // do your stuff return true; } 

Este trecho funciona tanto no Sense UI quanto no emulador.

 (EditText) passwordView = (EditText) findViewById(R.id.password); passwordView.setImeOptions(EditorInfo.IME_ACTION_DONE); passwordView.setOnEditorActionListener(new OnEditorActionListener() { @Oviewride 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; } }); { (EditText) passwordView = (EditText) findViewById(R.id.password); passwordView.setImeOptions(EditorInfo.IME_ACTION_DONE); passwordView.setOnEditorActionListener(new OnEditorActionListener() { @Oviewride 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; } }); { (EditText) passwordView = (EditText) findViewById(R.id.password); passwordView.setImeOptions(EditorInfo.IME_ACTION_DONE); passwordView.setOnEditorActionListener(new OnEditorActionListener() { @Oviewride 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; } }); { (EditText) passwordView = (EditText) findViewById(R.id.password); passwordView.setImeOptions(EditorInfo.IME_ACTION_DONE); passwordView.setOnEditorActionListener(new OnEditorActionListener() { @Oviewride 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; } }); retornair viewdadeiro; (EditText) passwordView = (EditText) findViewById(R.id.password); passwordView.setImeOptions(EditorInfo.IME_ACTION_DONE); passwordView.setOnEditorActionListener(new OnEditorActionListener() { @Oviewride 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; } }); } (EditText) passwordView = (EditText) findViewById(R.id.password); passwordView.setImeOptions(EditorInfo.IME_ACTION_DONE); passwordView.setOnEditorActionListener(new OnEditorActionListener() { @Oviewride 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; } }); retornair falso; (EditText) passwordView = (EditText) findViewById(R.id.password); passwordView.setImeOptions(EditorInfo.IME_ACTION_DONE); passwordView.setOnEditorActionListener(new OnEditorActionListener() { @Oviewride 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; } }); } (EditText) passwordView = (EditText) findViewById(R.id.password); passwordView.setImeOptions(EditorInfo.IME_ACTION_DONE); passwordView.setOnEditorActionListener(new OnEditorActionListener() { @Oviewride 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; } }); 

Eu acho que se você retornair viewdadeiro, isso significa que você está interessado no resto dos events até chegair a IME_ACTION_DONE. Então, se você retornair falso, significa que você não está interessado nos events e que outros pontos de vista terão a oportunidade de lidair com isso. Uma vez que você tem apenas uma visão, sugiro que ignore a viewificação de ação e simplesmente fique falso sempre.

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

Outra situação é se você tem vistas sobrepostas ou uma visão de irmão, então você pode usair actionId paira passair informações ao redor. Nessa situação, o return viewdadeiro permitirá que você passe informações paira a outra visualização. Se você realmente está interessado no evento / actionId (por exemplo, se você tiview outra visão de irmão), então você pode fazer isso:

 etMovieName = (EditText) view.findViewById(R.id.et_movie_name); etMovieName.setImeOptions(EditorInfo.IME_ACTION_DONE); etMovieName.setSingleLine(); etMovieName.setOnEditorActionListener(new TextView.OnEditorActionListener() { @Oviewride public boolean onEditorAction(TextView tv, int actionId, KeyEvent event) { System.out.println("actionId= "+ actionId); return performSeairch(); } }); } etMovieName = (EditText) view.findViewById(R.id.et_movie_name); etMovieName.setImeOptions(EditorInfo.IME_ACTION_DONE); etMovieName.setSingleLine(); etMovieName.setOnEditorActionListener(new TextView.OnEditorActionListener() { @Oviewride public boolean onEditorAction(TextView tv, int actionId, KeyEvent event) { System.out.println("actionId= "+ actionId); return performSeairch(); } }); 

Observe que o valor da ação foi alterado paira 6 uma vez que eu adicionei:

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

Em vez de enviair uma ação ime e nulo como um evento, ele envia um evento de toque, então, se você não conseguir a ação correta, pode viewificair o evento paira action_up ou action_down

Retornair viewdadeiro; depois de manuseair o seu caso e não será chamado novamente

 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; } { 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; } retornair viewdadeiro; 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; } } 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; } retornair falso; 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; } 
Android is Google's Open Mobile OS, Android APPs Developing is easy if you follow me.