SkbContainerpublic class SkbContainer extends android.widget.RelativeLayout implements android.view.View.OnTouchListenerThe top container to host soft keyboard view(s). |
Fields Summary |
---|
private static final int | Y_BIAS_CORRECTIONFor finger touch, user tends to press the bottom part of the target key,
or he/she even presses the area out of it, so it is necessary to make a
simple bias correction. If the input method runs on emulator, no bias
correction will be used. | private static final int | MOVE_TOLERANCEUsed to skip these move events whose position is too close to the
previous touch events. | private static boolean | POPUPWINDOW_FOR_PRESSED_UIIf this member is true, PopupWindow is used to show on-key highlight
effect. | private int | mSkbLayoutThe current soft keyboard layout. | private android.inputmethodservice.InputMethodService | mServiceThe input method service. | private InputModeSwitcher | mInputModeSwitcherInput mode switcher used to switch between different modes like Chinese,
English, etc. | private android.view.GestureDetector | mGestureDetectorThe gesture detector. | private Environment | mEnvironment | private android.widget.ViewFlipper | mSkbFlipper | private BalloonHint | mBalloonPopupThe popup balloon hint for key press/release. | private BalloonHint | mBalloonOnKeyThe on-key balloon hint for key press/release. | private SoftKeyboardView | mMajorViewThe major sub soft keyboard. | private boolean | mLastCandidatesShowingThe last parameter when function {@link #toggleCandidateMode(boolean)}
was called. | private boolean | mPopupSkbShowUsed to indicate whether a popup soft keyboard is shown. | private boolean | mPopupSkbNoResponseUsed to indicate whether a popup soft keyboard is just shown, and waits
for the touch event to release. After the release, the popup window can
response to touch events. | private android.widget.PopupWindow | mPopupSkbPopup sub keyboard. | private SoftKeyboardView | mPopupSkbViewThe view of the popup sub soft keyboard. | private int | mPopupX | private int | mPopupY | private volatile boolean | mWaitForTouchUpWhen user presses a key, a timer is started, when it times out, it is
necessary to detect whether user still holds the key. | private volatile boolean | mDiscardEventWhen user drags on the soft keyboard and the distance is enough, this
drag will be recognized as a gesture and a gesture-based action will be
taken, in this situation, ignore the consequent events. | private int | mYBiasCorrectionFor finger touch, user tends to press the bottom part of the target key,
or he/she even presses the area out of it, so it is necessary to make a
simple bias correction in Y. | private int | mXLastThe x coordination of the last touch event. | private int | mYLastThe y coordination of the last touch event. | private SoftKeyboardView | mSkvThe soft keyboard view. | private int[] | mSkvPosInContainerThe position of the soft keyboard view in the container. | private SoftKey | mSoftKeyDownThe key pressed by user. | private LongPressTimer | mLongPressTimerUsed to timeout a press if user holds the key for a long time. | private int[] | mXyPosTmpFor temporary use. |
Constructors Summary |
---|
public SkbContainer(android.content.Context context, android.util.AttributeSet attrs)
super(context, attrs);
mEnvironment = Environment.getInstance();
mLongPressTimer = new LongPressTimer(this);
// If it runs on an emulator, no bias correction
if ("1".equals(SystemProperties.get("ro.kernel.qemu"))) {
mYBiasCorrection = 0;
} else {
mYBiasCorrection = Y_BIAS_CORRECTION;
}
mBalloonPopup = new BalloonHint(context, this, MeasureSpec.AT_MOST);
if (POPUPWINDOW_FOR_PRESSED_UI) {
mBalloonOnKey = new BalloonHint(context, this, MeasureSpec.AT_MOST);
}
mPopupSkb = new PopupWindow(mContext);
mPopupSkb.setBackgroundDrawable(null);
mPopupSkb.setClippingEnabled(false);
|
Methods Summary |
---|
private void | dimSoftKeyboard(boolean dimSkb)
mMajorView.dimSoftKeyboard(dimSkb);
| private void | dismissPopupSkb()
mPopupSkb.dismiss();
mPopupSkbShow = false;
dimSoftKeyboard(false);
resetKeyPress(0);
| public void | dismissPopups()
handleBack(true);
resetKeyPress(0);
| public boolean | handleBack(boolean realAction)
if (mPopupSkbShow) {
if (!realAction) return true;
dismissPopupSkb();
mDiscardEvent = true;
return true;
}
return false;
| private SoftKeyboardView | inKeyboardView(int x, int y, int[] positionInParent)
if (mPopupSkbShow) {
if (mPopupX <= x && mPopupX + mPopupSkb.getWidth() > x
&& mPopupY <= y && mPopupY + mPopupSkb.getHeight() > y) {
positionInParent[0] = mPopupX;
positionInParent[1] = mPopupY;
mPopupSkbView.setOffsetToSkbContainer(positionInParent);
return mPopupSkbView;
}
return null;
}
return mMajorView;
| public boolean | isCurrentSkbSticky()
if (null == mMajorView) return true;
SoftKeyboard skb = mMajorView.getSoftKeyboard();
if (null != skb) {
return skb.getStickyFlag();
}
return true;
| protected void | onMeasure(int widthMeasureSpec, int heightMeasureSpec)
Environment env = Environment.getInstance();
int measuredWidth = env.getScreenWidth();
int measuredHeight = getPaddingTop();
measuredHeight += env.getSkbHeight();
widthMeasureSpec = MeasureSpec.makeMeasureSpec(measuredWidth,
MeasureSpec.EXACTLY);
heightMeasureSpec = MeasureSpec.makeMeasureSpec(measuredHeight,
MeasureSpec.EXACTLY);
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
| public boolean | onTouch(android.view.View v, android.view.MotionEvent event)
// Translate the event to fit to the container.
MotionEvent newEv = MotionEvent.obtain(event.getDownTime(), event
.getEventTime(), event.getAction(), event.getX() + mPopupX,
event.getY() + mPopupY, event.getPressure(), event.getSize(),
event.getMetaState(), event.getXPrecision(), event
.getYPrecision(), event.getDeviceId(), event
.getEdgeFlags());
boolean ret = onTouchEvent(newEv);
return ret;
| public boolean | onTouchEvent(android.view.MotionEvent event)
super.onTouchEvent(event);
if (mSkbFlipper.isFlipping()) {
resetKeyPress(0);
return true;
}
int x = (int) event.getX();
int y = (int) event.getY();
// Bias correction
y = y + mYBiasCorrection;
// Ignore short-distance movement event to get better performance.
if (event.getAction() == MotionEvent.ACTION_MOVE) {
if (Math.abs(x - mXLast) <= MOVE_TOLERANCE
&& Math.abs(y - mYLast) <= MOVE_TOLERANCE) {
return true;
}
}
mXLast = x;
mYLast = y;
if (!mPopupSkbShow) {
if (mGestureDetector.onTouchEvent(event)) {
resetKeyPress(0);
mDiscardEvent = true;
return true;
}
}
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
resetKeyPress(0);
mWaitForTouchUp = true;
mDiscardEvent = false;
mSkv = null;
mSoftKeyDown = null;
mSkv = inKeyboardView(x, y, mSkvPosInContainer);
if (null != mSkv) {
mSoftKeyDown = mSkv.onKeyPress(x - mSkvPosInContainer[0], y
- mSkvPosInContainer[1], mLongPressTimer, false);
}
break;
case MotionEvent.ACTION_MOVE:
if (x < 0 || x >= getWidth() || y < 0 || y >= getHeight()) {
break;
}
if (mDiscardEvent) {
resetKeyPress(0);
break;
}
if (mPopupSkbShow && mPopupSkbNoResponse) {
break;
}
SoftKeyboardView skv = inKeyboardView(x, y, mSkvPosInContainer);
if (null != skv) {
if (skv != mSkv) {
mSkv = skv;
mSoftKeyDown = mSkv.onKeyPress(x - mSkvPosInContainer[0], y
- mSkvPosInContainer[1], mLongPressTimer, true);
} else if (null != skv) {
if (null != mSkv) {
mSoftKeyDown = mSkv.onKeyMove(
x - mSkvPosInContainer[0], y
- mSkvPosInContainer[1]);
if (null == mSoftKeyDown) {
mDiscardEvent = true;
}
}
}
}
break;
case MotionEvent.ACTION_UP:
if (mDiscardEvent) {
resetKeyPress(0);
break;
}
mWaitForTouchUp = false;
// The view which got the {@link MotionEvent#ACTION_DOWN} event is
// always used to handle this event.
if (null != mSkv) {
mSkv.onKeyRelease(x - mSkvPosInContainer[0], y
- mSkvPosInContainer[1]);
}
if (!mPopupSkbShow || !mPopupSkbNoResponse) {
responseKeyEvent(mSoftKeyDown);
}
if (mSkv == mPopupSkbView && !mPopupSkbNoResponse) {
dismissPopupSkb();
}
mPopupSkbNoResponse = false;
break;
case MotionEvent.ACTION_CANCEL:
break;
}
if (null == mSkv) {
return false;
}
return true;
| private void | popupSymbols()
int popupResId = mSoftKeyDown.getPopupResId();
if (popupResId > 0) {
int skbContainerWidth = getWidth();
int skbContainerHeight = getHeight();
// The paddings of the background are not included.
int miniSkbWidth = (int) (skbContainerWidth * 0.8);
int miniSkbHeight = (int) (skbContainerHeight * 0.23);
SkbPool skbPool = SkbPool.getInstance();
SoftKeyboard skb = skbPool.getSoftKeyboard(popupResId, popupResId,
miniSkbWidth, miniSkbHeight, mContext);
if (null == skb) return;
mPopupX = (skbContainerWidth - skb.getSkbTotalWidth()) / 2;
mPopupY = (skbContainerHeight - skb.getSkbTotalHeight()) / 2;
if (null == mPopupSkbView) {
mPopupSkbView = new SoftKeyboardView(mContext, null);
mPopupSkbView.onMeasure(LayoutParams.WRAP_CONTENT,
LayoutParams.WRAP_CONTENT);
}
mPopupSkbView.setOnTouchListener(this);
mPopupSkbView.setSoftKeyboard(skb);
mPopupSkbView.setBalloonHint(mBalloonOnKey, mBalloonPopup, true);
mPopupSkb.setContentView(mPopupSkbView);
mPopupSkb.setWidth(skb.getSkbCoreWidth()
+ mPopupSkbView.getPaddingLeft()
+ mPopupSkbView.getPaddingRight());
mPopupSkb.setHeight(skb.getSkbCoreHeight()
+ mPopupSkbView.getPaddingTop()
+ mPopupSkbView.getPaddingBottom());
getLocationInWindow(mXyPosTmp);
mPopupSkb.showAtLocation(this, Gravity.NO_GRAVITY, mPopupX, mPopupY
+ mXyPosTmp[1]);
mPopupSkbShow = true;
mPopupSkbNoResponse = true;
// Invalidate itself to dim the current soft keyboards.
dimSoftKeyboard(true);
resetKeyPress(0);
}
| private void | resetKeyPress(long delay)
mLongPressTimer.removeTimer();
if (null != mSkv) {
mSkv.resetKeyPress(delay);
}
| private void | responseKeyEvent(SoftKey sKey)
if (null == sKey) return;
((PinyinIME) mService).responseSoftKeyEvent(sKey);
return;
| public void | setGestureDetector(android.view.GestureDetector gestureDetector)
mGestureDetector = gestureDetector;
| public void | setInputModeSwitcher(InputModeSwitcher inputModeSwitcher)
mInputModeSwitcher = inputModeSwitcher;
| public void | setService(android.inputmethodservice.InputMethodService service)
mService = service;
| public void | toggleCandidateMode(boolean candidatesShowing)
if (null == mMajorView || !mInputModeSwitcher.isChineseText()
|| mLastCandidatesShowing == candidatesShowing) return;
mLastCandidatesShowing = candidatesShowing;
SoftKeyboard skb = mMajorView.getSoftKeyboard();
if (null == skb) return;
int state = mInputModeSwitcher.getTooggleStateForCnCand();
if (!candidatesShowing) {
skb.disableToggleState(state, false);
skb.enableToggleStates(mInputModeSwitcher.getToggleStates());
} else {
skb.enableToggleState(state, false);
}
mMajorView.invalidate();
| public void | updateInputMode()
int skbLayout = mInputModeSwitcher.getSkbLayout();
if (mSkbLayout != skbLayout) {
mSkbLayout = skbLayout;
updateSkbLayout();
}
mLastCandidatesShowing = false;
if (null == mMajorView) return;
SoftKeyboard skb = mMajorView.getSoftKeyboard();
if (null == skb) return;
skb.enableToggleStates(mInputModeSwitcher.getToggleStates());
invalidate();
return;
| private void | updateSkbLayout()
int screenWidth = mEnvironment.getScreenWidth();
int keyHeight = mEnvironment.getKeyHeight();
int skbHeight = mEnvironment.getSkbHeight();
Resources r = mContext.getResources();
if (null == mSkbFlipper) {
mSkbFlipper = (ViewFlipper) findViewById(R.id.alpha_floatable);
}
mMajorView = (SoftKeyboardView) mSkbFlipper.getChildAt(0);
SoftKeyboard majorSkb = null;
SkbPool skbPool = SkbPool.getInstance();
switch (mSkbLayout) {
case R.xml.skb_qwerty:
majorSkb = skbPool.getSoftKeyboard(R.xml.skb_qwerty,
R.xml.skb_qwerty, screenWidth, skbHeight, mContext);
break;
case R.xml.skb_sym1:
majorSkb = skbPool.getSoftKeyboard(R.xml.skb_sym1, R.xml.skb_sym1,
screenWidth, skbHeight, mContext);
break;
case R.xml.skb_sym2:
majorSkb = skbPool.getSoftKeyboard(R.xml.skb_sym2, R.xml.skb_sym2,
screenWidth, skbHeight, mContext);
break;
case R.xml.skb_smiley:
majorSkb = skbPool.getSoftKeyboard(R.xml.skb_smiley,
R.xml.skb_smiley, screenWidth, skbHeight, mContext);
break;
case R.xml.skb_phone:
majorSkb = skbPool.getSoftKeyboard(R.xml.skb_phone,
R.xml.skb_phone, screenWidth, skbHeight, mContext);
break;
default:
}
if (null == majorSkb || !mMajorView.setSoftKeyboard(majorSkb)) {
return;
}
mMajorView.setBalloonHint(mBalloonOnKey, mBalloonPopup, false);
mMajorView.invalidate();
|
|