MultiTapKeyListenerpublic class MultiTapKeyListener extends BaseKeyListener implements SpanWatcherThis is the standard key listener for alphabetic input on 12-key
keyboards. You should generally not need to instantiate this yourself;
TextKeyListener will do it for you.
As for all implementations of {@link KeyListener}, this class is only concerned
with hardware keyboards. Software input methods have no obligation to trigger
the methods in this class. |
Fields Summary |
---|
private static MultiTapKeyListener[] | sInstance | private static final android.util.SparseArray | sRecs | private android.text.method.TextKeyListener.Capitalize | mCapitalize | private boolean | mAutoText |
Constructors Summary |
---|
public MultiTapKeyListener(android.text.method.TextKeyListener.Capitalize cap, boolean autotext)
sRecs.put(KeyEvent.KEYCODE_1, ".,1!@#$%^&*:/?'=()");
sRecs.put(KeyEvent.KEYCODE_2, "abc2ABC");
sRecs.put(KeyEvent.KEYCODE_3, "def3DEF");
sRecs.put(KeyEvent.KEYCODE_4, "ghi4GHI");
sRecs.put(KeyEvent.KEYCODE_5, "jkl5JKL");
sRecs.put(KeyEvent.KEYCODE_6, "mno6MNO");
sRecs.put(KeyEvent.KEYCODE_7, "pqrs7PQRS");
sRecs.put(KeyEvent.KEYCODE_8, "tuv8TUV");
sRecs.put(KeyEvent.KEYCODE_9, "wxyz9WXYZ");
sRecs.put(KeyEvent.KEYCODE_0, "0+");
sRecs.put(KeyEvent.KEYCODE_POUND, " ");
mCapitalize = cap;
mAutoText = autotext;
|
Methods Summary |
---|
public int | getInputType()
return makeTextContentType(mCapitalize, mAutoText);
| public static android.text.method.MultiTapKeyListener | getInstance(boolean autotext, android.text.method.TextKeyListener.Capitalize cap)Returns a new or existing instance with the specified capitalization
and correction properties.
int off = cap.ordinal() * 2 + (autotext ? 1 : 0);
if (sInstance[off] == null) {
sInstance[off] = new MultiTapKeyListener(cap, autotext);
}
return sInstance[off];
| public boolean | onKeyDown(android.view.View view, Editable content, int keyCode, android.view.KeyEvent event)
int selStart, selEnd;
int pref = 0;
if (view != null) {
pref = TextKeyListener.getInstance().getPrefs(view.getContext());
}
{
int a = Selection.getSelectionStart(content);
int b = Selection.getSelectionEnd(content);
selStart = Math.min(a, b);
selEnd = Math.max(a, b);
}
int activeStart = content.getSpanStart(TextKeyListener.ACTIVE);
int activeEnd = content.getSpanEnd(TextKeyListener.ACTIVE);
// now for the multitap cases...
// Try to increment the character we were working on before
// if we have one and it's still the same key.
int rec = (content.getSpanFlags(TextKeyListener.ACTIVE)
& Spannable.SPAN_USER) >>> Spannable.SPAN_USER_SHIFT;
if (activeStart == selStart && activeEnd == selEnd &&
selEnd - selStart == 1 &&
rec >= 0 && rec < sRecs.size()) {
if (keyCode == KeyEvent.KEYCODE_STAR) {
char current = content.charAt(selStart);
if (Character.isLowerCase(current)) {
content.replace(selStart, selEnd,
String.valueOf(current).toUpperCase());
removeTimeouts(content);
new Timeout(content); // for its side effects
return true;
}
if (Character.isUpperCase(current)) {
content.replace(selStart, selEnd,
String.valueOf(current).toLowerCase());
removeTimeouts(content);
new Timeout(content); // for its side effects
return true;
}
}
if (sRecs.indexOfKey(keyCode) == rec) {
String val = sRecs.valueAt(rec);
char ch = content.charAt(selStart);
int ix = val.indexOf(ch);
if (ix >= 0) {
ix = (ix + 1) % (val.length());
content.replace(selStart, selEnd, val, ix, ix + 1);
removeTimeouts(content);
new Timeout(content); // for its side effects
return true;
}
}
// Is this key one we know about at all? If so, acknowledge
// that the selection is our fault but the key has changed
// or the text no longer matches, so move the selection over
// so that it inserts instead of replaces.
rec = sRecs.indexOfKey(keyCode);
if (rec >= 0) {
Selection.setSelection(content, selEnd, selEnd);
selStart = selEnd;
}
} else {
rec = sRecs.indexOfKey(keyCode);
}
if (rec >= 0) {
// We have a valid key. Replace the selection or insertion point
// with the first character for that key, and remember what
// record it came from for next time.
String val = sRecs.valueAt(rec);
int off = 0;
if ((pref & TextKeyListener.AUTO_CAP) != 0 &&
TextKeyListener.shouldCap(mCapitalize, content, selStart)) {
for (int i = 0; i < val.length(); i++) {
if (Character.isUpperCase(val.charAt(i))) {
off = i;
break;
}
}
}
if (selStart != selEnd) {
Selection.setSelection(content, selEnd);
}
content.setSpan(OLD_SEL_START, selStart, selStart,
Spannable.SPAN_MARK_MARK);
content.replace(selStart, selEnd, val, off, off + 1);
int oldStart = content.getSpanStart(OLD_SEL_START);
selEnd = Selection.getSelectionEnd(content);
if (selEnd != oldStart) {
Selection.setSelection(content, oldStart, selEnd);
content.setSpan(TextKeyListener.LAST_TYPED,
oldStart, selEnd,
Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
content.setSpan(TextKeyListener.ACTIVE,
oldStart, selEnd,
Spannable.SPAN_EXCLUSIVE_EXCLUSIVE |
(rec << Spannable.SPAN_USER_SHIFT));
}
removeTimeouts(content);
new Timeout(content); // for its side effects
// Set up the callback so we can remove the timeout if the
// cursor moves.
if (content.getSpanStart(this) < 0) {
KeyListener[] methods = content.getSpans(0, content.length(),
KeyListener.class);
for (Object method : methods) {
content.removeSpan(method);
}
content.setSpan(this, 0, content.length(),
Spannable.SPAN_INCLUSIVE_INCLUSIVE);
}
return true;
}
return super.onKeyDown(view, content, keyCode, event);
| public void | onSpanAdded(Spannable s, java.lang.Object what, int start, int end)
| public void | onSpanChanged(Spannable buf, java.lang.Object what, int s, int e, int start, int stop)
if (what == Selection.SELECTION_END) {
buf.removeSpan(TextKeyListener.ACTIVE);
removeTimeouts(buf);
}
| public void | onSpanRemoved(Spannable s, java.lang.Object what, int start, int end)
| private static void | removeTimeouts(Spannable buf)
Timeout[] timeout = buf.getSpans(0, buf.length(), Timeout.class);
for (int i = 0; i < timeout.length; i++) {
Timeout t = timeout[i];
t.removeCallbacks(t);
t.mBuffer = null;
buf.removeSpan(t);
}
|
|