2014-05-17 3 views
16

Cyril Mottier has a great post on customizing the send/done/return key on the Android soft keyboard. Podczas wypróbowywania kodu, ja (i kilka innych w komentarzach) zauważyłem, że ustawienie ImeActionId z nowym ID w XML (np. @ + Id/...) zwraca 0 do OnEditorActionListener, gdy klucz jest trafiony przez użytkownika, a nie unikalny identyfikator. Jeśli jednak ustawisz identyfikator w pliku ids.xml i ustawisz w nim wartość imeActionId (np. W/@id/...), spowoduje to błąd układu.Dlaczego ustawienie parametru imeActionId z predefiniowanym zasobem ID powoduje błąd?

Jedynym sposobem, w jaki mogłem uzyskać identyfikator IMeActionId, który miałby być ustawiony na unikalny identyfikator, było ustawienie programowe w Javie. Jakie jest prawidłowe użycie atrybutu XML imeActionId?

Oto Gist z wszystkich moich kodu: https://gist.github.com/gsysko/d46adbe27d409bde0299

Dzięki za zważywszy na to pytanie.

Odpowiedz

27

Powód jest taki, że imeActionId jest w tym przypadku niewielkim błędem. Dokumentacja Javadoc dla imeActionId mówi:

Podaj wartość dla EditorInfo.actionId używaną, gdy metoda wprowadzania jest połączona z widokiem tekstowym.

Szuka przydziału wartości. Identyfikator zasobu służy do identyfikowania zasobów w Twojej aplikacji i nie ma gwarantowanej wartości. W niektórych przypadkach można dokonywać porównań na podstawie identyfikatorów zasobów, takich jak View.getId(), ale nie jest dobrze mieszać identyfikatory zasobów z wartościami stałymi, których używa EditorInfo. Android może próbować uniemożliwić ci to, pisząc w swoich plikach XML, wyrzucając wyjątki, jakie widziałeś, ale nie ma wielu kontroli, które może wykonać w środowisku wykonawczym, jeśli ustawisz je programowo.

Zamiast tego, można określić wartość całkowitą w swoich zasobach tak:

<!--res/values/integers.xml--> 
<resources> 
<item type="integer" name="customImeActionId" format="integer">100</item> 
</resources> 

i używać go jak

android:imeActionId="@integer/customImeActionId" 

w kodzie można następnie pobrać go

int imeActionId = getResources().getInteger(R.integer.customImeActionId); 

edytuj: OK, wzbudziło to moje zainteresowanie, więc patrząc dalej w kodzie źródłowym Androida, TextView analizuje attr ibute lubię:

mEditor.mInputContentType.imeActionId = a.getInt(attr, mEditor.mInputContentType.imeActionId); 

Wykorzysta mEditor.mInputContentType.imeActionId jako wartości domyślne - która wynosi 0 w tym przypadku - jeśli nie może znaleźć wartość INT attr, co wyjaśnia, dlaczego zwraca 0, jeśli używasz nowo utworzony identyfikator. Nie znalazłem przyczyny błędu inflacji.

+1

Dzięki. Twoje rozwiązanie z zasobem Integer na pewno działa. Zastanawia mnie, że Cyril wyraźnie wspomina, że ​​nie użył zasobu Integer w swoich komentarzach do pierwotnego postu. Ciekawi mnie, jak udało mu się to zrobić z identyfikatorem? – gsysko