问题
Im working on an input method for android and one of the tasks is to implement a custom popup keyboard for hard keyboard key presses. Usually input methods let the editor handle that but the thing is I need to add more symbols than android supports. So I implemented the popup keyboard and even have it displaying well when a hard key (character key) is long pressed.
The steps I've followed are:
- Create popup window.
- Inflate a linear layout which contains a keyboardview and a close button and save it to a view object
- bind the keyboardview and close buttons to the relevant objects
- Create a keyboard for the popup characters and set it as the keyboard for the keyboard view. The keyboard has a column limit of 5.
- set the linear layout as the content view for the popup window
- Display the popup window
THE ISSUE: If there are multiple rows in the popup keyboard I am only able to select key in the last row for the column. Even if I click on the key in the first row of that column, the key in the last row gets selected. If anyone could explain why this is happening and how do I fix it, Id appreciate it.
THE CODE:
PopupWindow mPopupKeyboard = new PopupWindow(this.getBaseContext());
mPopupKeyboard.setBackgroundDrawable(null);
if(mPopupKeyboard != null)
{
this.dismissPopupKeyboard();
View mMiniKeyboardContainer = null;
KeyboardView mMiniKeyboard = null;
View closeButton = null;
mMiniKeyboardContainer = getLayoutInflater().inflate(R.layout.keyboard_popup_keyboard, null);
mMiniKeyboard = (KeyboardView) mMiniKeyboardContainer.findViewById(R.id.popup_keyboardView);
closeButton = mMiniKeyboardContainer.findViewById(R.id.closeButton);
if (closeButton != null)
{
closeButton.setOnClickListener(new OnClickListener()
{
@Override
public void onClick(View arg0)
{
mPopupKeyboard.dismiss();
});
}
mMiniKeyboard.setOnKeyboardActionListener(this);
String resourcestring = "abcdefghi";
mMiniKeyboard.setKeyboard(new Keyboard(this.getBaseContext(), R.xml.kbd_popup_template, alternates, 3, 0));
mMiniKeyboard.setPopupParent(mCandidateView);
mPopupKeyboard.setContentView(mMiniKeyboardContainer);
mPopupKeyboard.setWidth(LayoutParams.WRAP_CONTENT);
mPopupKeyboard.setHeight(LayoutParams.WRAP_CONTENT);
mPopupKeyboard.showAtLocation(mCandidateView, Gravity.TOP, 0, 0);
}
回答1:
I had a similar problem with popup keyboards. I found that it was a problem only with Android 2.3. My only workaround was to avoid popup keyboards with more than one row.
回答2:
The reason this occurs is because KeyboardView sends off the MotionEvent. MotionEvent.getRawX() and getRawY() only return coordinates within the bounds of KeyboardView. If the MotionEvent happens above KeyboardView, it returns the closest absolute coordinates in KeyboardView.
One solution is to create an invisible View above KeyboardView. It will have to detect the MotionEvent and then pass the MotionEvent back to KeyboardView and then your multirow popup keyboard will work
For the starting code look at CandidateViews above the KeyboardView. For example look at this project: https://github.com/blackcj/AndroidCustomKeyboard
In the
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec)
(https://github.com/blackcj/AndroidCustomKeyboard/blob/master/app/src/main/java/com/blackcj/customkeyboard/CandidateView.java)
method add 200 to desiredHeight in this statement:
setMeasuredDimension(measuredWidth, resolveSize(desiredHeight, heightMeasureSpec));
Notice how this will cause the motionEvent.getRawY() to work for an extra 200p in height
来源:https://stackoverflow.com/questions/9350654/popup-keyboard-issue-in-android-when-column-limits-are-specified