在 Android 中,当输入键盘启动时创建 IME,如何在 EditText 上实现?

4
我正在为设备创建自己的输入法。我需要添加一个文本框到键盘视图上方,如下图所示。虽然我可以像下图显示一样显示它,但是我无法在其中写入文本。
我正在扩展键盘视图,以下是布局结构:
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/wrapper"
    android:layout_height="wrap_content" android:orientation="vertical" 
    android:layout_width="fill_parent" android:background="@color/background" > 

   <TextView android:textAppearance="?android:attr/textAppearanceMedium" android:layout_height="wrap_content" android:id="@+id/txtTest" android:layout_width="fill_parent" android:text="Test" ></TextView>
       <EditText android:inputType="text" android:id="@+id/edtTest" android:layout_height="wrap_content" android:layout_width="fill_parent"></EditText>

<com.keyboard.CustomKeyboardView
            xmlns:android="http://schemas.android.com/apk/res/android"
            android:id="@+id/keyboard"
            android:layout_alignParentBottom="true"
            android:layout_width="fill_parent" android:layout_height="wrap_content"
            android:keyTextSize="15sp"
       />
  </LinearLayout>

公共类CustomKeyboardView扩展自KeyboardView。

static final int KEYCODE_OPTIONS = -100;

private TextView mResultText;
public CustomKeyboardView (Context context, AttributeSet attrs) {
    super(context, attrs);
    }

public CustomKeyboardView(Context context, AttributeSet attrs, int defStyle) {
    super(context, attrs, defStyle);
}

@Override
protected boolean onLongPress(Key key) {
    if (key.codes[0] == Keyboard.KEYCODE_CANCEL) {
        getOnKeyboardActionListener().onKey(KEYCODE_OPTIONS, null);
        return true;
    } else {
        return super.onLongPress(key);
    }
}

谢谢,Nil。

你能提供至少你的布局吗?你是在扩展KeyboardView吗? - Laurent'
@Laurent更新了代码,我需要在布局中添加其他内容吗? - nilMoBile
我认为这是您的活动布局,而不是您的CustomKeyboardView布局。您可以提供CustomKeyboardView布局(或onCreate())吗? - Laurent'
你想在哪个文本框中输入文本?EditText 还是 TextView?这个布局是你的应用程序的还是你的输入法服务的布局? - Laurent'
@Laurent,我添加的上面的布局是input.xml,在OnCreateInputView中我们正在加载此布局。CustomKeyboardView中没有添加任何代码,仅进行了编辑以澄清它。 - nilMoBile
1个回答

2
你可以通过实现KeyboardView.OnKeyboardActionListener,来捕获软键盘事件并将其传输到自己的小部件中。
在你的Inputmethodservice.onKey()方法中,你应该尝试像这样将事件传输到你的InputView子视图中:
public class mySoftKeyboard 
    extends InputMethodService 
    implements KeyboardView.OnKeyboardActionListener {

// Implementation of KeyboardViewListener inside your InputMethodService
public void onKey(int primaryCode, int[] keyCodes) {
        //assuming your inputview is in private variable mInputView 
        //and contains public members txtTst and edtTst views 
        //(arrange for this in your InputView.onCreate)
        //Here, we just transmit the onKey code to View.onKeyDown/Up and let views draw themselves
        sendKey( mInputView.txtTst , primaryCode ); // send this to your TextView
        sendKey( mInputView.edtTst , primaryCode ); // also send to your EditText
    }

/**
 * Helper to send a character to the editor as raw key events.
 */
private void sendKey(View v, int keyCode) {
          v.onKeyDown(keyCode,new KeyEvent(KeyEvent.ACTION_DOWN, keyCode));
          v.onKeyUp  (keyCode,new KeyEvent(KeyEvent.ACTION_UP, keyCode));
}
    //other interface function, no need to implement
public void onText(CharSequence text){}
public void swipeRight() {}
public void swipeLeft() {}
public void swipeDown() {}
public void swipeUp() {}
public void onPress(int primaryCode) {}
public void onRelease(int primaryCode) {}
}

编辑

为了回答你关于字形和按键代码之间的区别的评论,这里有一段代码片段可以帮助你:

//This snippet tries to translate the glyph 'primaryCode' into key events

//retrieve the keycharacter map from a keyEvent (build yourself a default event if needed)
KeyCharacterMap myMap=KeyCharacterMap.load(event.getDeviceId()); 

//event list to reproduce glyph
KeyEvent evs[]=null;

//put the primariCode into an array
char chars[]=new char[1];
chars[0]=primaryCode;

// retrieve the key events that could have produced this glyph
evs=myMap.getEvents(chars);

if (evs != null){
    // we can reproduce this glyph with this key event array
    for (int i=0; i< evs.length;i++) mySendKeyMethodHelper(evs[i]);
}
else { /* could not find a way to reproduce this glyph */ }

1
绑定到具有焦点的字段(在您的情况下为To字段)。按设计。您仍然可以在onKey中获取关键事件并将其推迟到自己的文本视图中。 - Laurent'
1
我忘了提醒你必须实现OnKeyboardActionListener接口以便有机会捕获按键。请查看更新后的代码。 - Laurent'
谢谢Laurent,你真是个救命稻草...终于按照你的建议做到了。唯一的问题是它没有显示出准确的字符。但我会解决的,可能需要处理primarycode或keycodes,可能与Unicode有关之类的... - nilMoBile
@nilMoBile 我刚刚添加了一个代码片段到我的软键盘来处理这种问题。诀窍是获取 KeyCharacterMap 并使用它将 Unicode 字符转换为 keyEvents 列表。(要将字符发送到 textview,需要获取 InputConnection,我发现只有在 editext 有焦点时才可用) - Laurent'
抱歉我的说法有误:我昨天添加的代码片段不需要InputConnection。它所做的只是生成一个键盘事件数组,可以发送到您的视图中以还原字符。 - Laurent'
显示剩余2条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接