/*
* Copyright (C) 2008-2009 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy of
* the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
*/
package com.example.android.softkeyboard;
import android.inputmethodservice.InputMethodService;
import android.inputmethodservice.Keyboard;
import android.inputmethodservice.KeyboardView;
import android.text.method.MetaKeyKeyListener;
import android.util.Log;
import android.view.KeyCharacterMap;
import android.view.KeyEvent;
import android.view.View;
import android.view.inputmethod.CompletionInfo;
import android.view.inputmethod.EditorInfo;
import android.view.inputmethod.InputConnection;
import android.view.inputmethod.InputMethodManager;
import java.util.ArrayList;
import java.util.List;
/**
* Example of writing an input method for a soft keyboard. This code is
* focused on simplicity over completeness, so it should in no way be considered
* to be a complete soft keyboard implementation. Its purpose is to provide
* a basic example for how you would get started writing an input method, to
* be fleshed out as appropriate.
*/
public class SoftKeyboard extends InputMethodService
implements KeyboardView.OnKeyboardActionListener {
static final boolean DEBUG = false;
/**
* This boolean indicates the optional example code for performing
* processing of hard keys in addition to regular text generation
* from on-screen interaction. It would be used for input methods that
* perform language translations (such as converting text entered on
* a QWERTY keyboard to Chinese), but may not be used for input methods
* that are primarily intended to be used for on-screen text entry.
*/
static final boolean PROCESS_HARD_KEYS = true;
private KeyboardView mInputView;
private CandidateView mCandidateView;
private CompletionInfo[] mCompletions;
private StringBuilder mComposing = new StringBuilder();
private boolean mPredictionOn;
private boolean mCompletionOn;
private int mLastDisplayWidth;
private boolean mCapsLock;
private long mLastShiftTime;
private long mMetaState;
private LatinKeyboard mSymbolsKeyboard;
private LatinKeyboard mSymbolsShiftedKeyboard;
private LatinKeyboard mQwertyKeyboard;
private LatinKeyboard mCurKeyboard;
private String mWordSeparators;
/**
* Main initialization of the input method component. Be sure to call
* to super class.
*/
@Override public void onCreate() {
super.onCreate();
mWordSeparators = getResources().getString(R.string.word_separators);
}
/**
* This is the point where you can do all of your UI initialization. It
* is called after creation and any configuration change.
*/
@Override public void onInitializeInterface() {
if (mQwertyKeyboard != null) {
// Configuration changes can happen after the keyboard gets recreated,
// so we need to be able to re-build the keyboards if the available
// space has changed.
int displayWidth = getMaxWidth();
if (displayWidth == mLastDisplayWidth) return;
mLastDisplayWidth = displayWidth;
}
mQwertyKeyboard = new LatinKeyboard(this, R.xml.qwerty);
mSymbolsKeyboard = new LatinKeyboard(this, R.xml.symbols);
mSymbolsShiftedKeyboard = new LatinKeyboard(this, R.xml.symbols_shift);
}
/**
* Called by the framework when your view for creating input needs to
* be generated. This will be called the first time your input method
* is displayed, and every time it needs to be re-created such as due to
* a configuration change.
*/
@Override public View onCreateInputView() {
mInputView = (KeyboardView) getLayoutInflater().inflate(
R.layout.input, null);
mInputView.setOnKeyboardActionListener(this);
mInputView.setKeyboard(mQwertyKeyboard);
return mInputView;
}
/**
* Called by the framework when your view for showing candidates needs to
* be generated, like {@link #onCreateInputView}.
*/
@Override public View onCreateCandidatesView() {
mCandidateView = new CandidateView(this);
mCandidateView.setService(this);
return mCandidateView;
}
/**
* This is the main point where we do our initialization of the input method
* to begin operating on an application. At this point we have been
* bound to the client, and are now receiving all of the detailed information
* about the target of our edits.
*/
@Override public void onStartInput(EditorInfo attribute, boolean restarting) {
super.onStartInput(attribute, restarting);
// Reset our state. We want to do this even if restarting, because
// the underlying state of the text editor could have changed in any way.
mComposing.setLength(0);
updateCandidates();
if (!restarting) {
// Clear shift states.
mMetaState = 0;
}
mPredictionOn = false;
mCompletionOn = false;
mCompletions = null;
// We are now going to initialize our state based on the type of
// text being edited.
switch (attribute.inputType&EditorInfo.TYPE_MASK_CLASS) {
case EditorInfo.TYPE_CLASS_NUMBER:
case EditorInfo.TYPE_CLASS_DATETIME:
// Numbers and dates default to the symbols keyboard, with
// no extra features.
mCurKeyboard = mSymbolsKeyboard;
break;
case EditorInfo.TYPE_CLASS_PHONE:
// Phones will also default to the symbols keyboard, though
// often you will want to have a dedicated phone keyboard.
mCurKeyboard = mSymbolsKeyboard;
break;
case EditorInfo.TYPE_CLASS_TEXT:
// This is general text editing. We will default to the
// normal alphabetic keyboard, and assume that we should
// be doing predictive text (showing candidates as the
// user types).
mCurKeyboard = mQwertyKeyboard;
mPredictionOn = true;
// We now look for a few special variations of text that will
// modify our behavior.
int variation = attribute.inputType & EditorInfo.TYPE_MASK_VARIATION;
if (variation == EditorInfo.TYPE_TEXT_VARIATION_PASSWORD ||
variation == EditorInfo.TYPE_TEXT_VARIATION_VISIBLE_PASSWORD) {
// Do not display predictions / what the user is typing
// when they are entering a password.
mPredictionOn = false;
}
if (variation == EditorInfo.TYPE_TEXT_VARIATION_EMAIL_ADDRESS
|| variation == EditorInfo.TYPE_TEXT_VARIATION_URI
|| variation == EditorInfo.TYPE_TEXT_VARIATION_FILTER) {
// Our predictions are not useful for e-mail addresses
// or URIs.
mPredictionOn = false;
}
if ((attribute.inputType&EditorInfo.TYPE_TEXT_FLAG_AUTO_COMPLETE) != 0) {
// If this is an auto-complete text view,
评论30
最新资源