如何制作Android自定义键盘?

XX_*_*her 92 keyboard android

我想制作一个自定义键盘.我不知道如何在xml和activity中做到这一点.这张照片是我的键盘型号.它只需要数字.

在此输入图像描述

Pon*_*ios 78

首先,您需要一个keyboard.xml文件放在res/xml文件夹中(如果文件夹不存在,则创建它).

<?xml version="1.0" encoding="utf-8"?> 
<Keyboard xmlns:android="http://schemas.android.com/apk/res/android"
    android:keyWidth="15%p"
    android:keyHeight="15%p" >

    <Row>
        <Key android:codes="1"    android:keyLabel="1" android:horizontalGap="4%p"/>
        <Key android:codes="2"    android:keyLabel="2" android:horizontalGap="4%p"/>
        <Key android:codes="3"    android:keyLabel="3" android:horizontalGap="4%p" />
        <Key android:codes="4"    android:keyLabel="4" android:horizontalGap="4%p" />
        <Key android:codes="5"    android:keyLabel="5" android:horizontalGap="4%p" />
    </Row>
    <Row>
        <Key android:codes="6"    android:keyLabel="6" android:horizontalGap="4%p"/>
        <Key android:codes="7"    android:keyLabel="7" android:horizontalGap="4%p"/>
        <Key android:codes="8"    android:keyLabel="8" android:horizontalGap="4%p" />
        <Key android:codes="9"    android:keyLabel="9" android:horizontalGap="4%p" />
        <Key android:codes="0"    android:keyLabel="0" android:horizontalGap="4%p" />
    </Row>

    <Row>
        <Key android:codes="-1"    android:keyIcon="@drawable/backspace" android:keyWidth="34%p" android:horizontalGap="4%p"/>
        <Key android:codes="100"    android:keyLabel="Enter" android:keyWidth="53%p" android:horizontalGap="4%p"/>
    </Row>
 </Keyboard>
Run Code Online (Sandbox Code Playgroud)

**请注意,您必须创建backspacedrawable并将其放在res/drawable-ldpi文件夹中,其尺寸非常小(如18x18像素)

然后在您希望它使用的xml文件中(TextView所在的位置),您应该添加以下代码:

<RelativeLayout
 ...
>

        .....


        <android.inputmethodservice.KeyboardView
             android:id="@+id/keyboardview"
             android:layout_width="fill_parent"
             android:layout_height="wrap_content"
             android:layout_alignParentBottom="true"
             android:layout_centerHorizontal="true"
             android:focusable="true"
             android:focusableInTouchMode="true"
             android:visibility="gone" 
         />

        ......


</RelativeLayout>
Run Code Online (Sandbox Code Playgroud)

**请注意,您将放入的xml文件android.inputmethodservice.KeyboardView必须RelativeLayout是为了能够设置alignParentBottom="true"(通常键盘显示在屏幕的底部)

然后,您需要在处理要将键盘连接到的onCreate功能中添加以下代码ActivityTextView

    // Create the Keyboard
    mKeyboard= new Keyboard(this,R.xml.keyboard);

    // Lookup the KeyboardView
    mKeyboardView= (KeyboardView)findViewById(R.id.keyboardview);
    // Attach the keyboard to the view
    mKeyboardView.setKeyboard( mKeyboard );

    // Do not show the preview balloons
    //mKeyboardView.setPreviewEnabled(false);

    // Install the key handler
    mKeyboardView.setOnKeyboardActionListener(mOnKeyboardActionListener);
Run Code Online (Sandbox Code Playgroud)

**请注意,mKeyboard并且mKeyboardView您必须创建私有类变量.

然后你需要以下函数来打开键盘(你必须通过onClickxml属性将它与TextView相关联)

    public void openKeyboard(View v)
    {
       mKeyboardView.setVisibility(View.VISIBLE);
       mKeyboardView.setEnabled(true);
       if( v!=null)((InputMethodManager)getSystemService(Activity.INPUT_METHOD_SERVICE)).hideSoftInputFromWindow(v.getWindowToken(), 0);
    }
Run Code Online (Sandbox Code Playgroud)

最后,您需要OnKeyboardActionListener能够处理您的活动

private OnKeyboardActionListener mOnKeyboardActionListener = new OnKeyboardActionListener() {
    @Override public void onKey(int primaryCode, int[] keyCodes) 
    {
         //Here check the primaryCode to see which key is pressed 
         //based on the android:codes property
         if(primaryCode==1)
         {
            Log.i("Key","You just pressed 1 button");
         }
    }

    @Override public void onPress(int arg0) {
    }

    @Override public void onRelease(int primaryCode) {
    }

    @Override public void onText(CharSequence text) {
    }

    @Override public void swipeDown() {
    }

    @Override public void swipeLeft() {
    }

    @Override public void swipeRight() {
    }

    @Override public void swipeUp() {
    }
};
Run Code Online (Sandbox Code Playgroud)

希望有所帮助!

大多数代码都在这里找到

  • KeyboardView 已被谷歌弃用。什么是新的解决方案? (3认同)
  • 如果我不希望键盘位于屏幕底部怎么办?(例如,我希望用户能够拖动它)。这是我可以通过我的键盘应用程序控制的东西还是由安卓系统处理? (2认同)

Sur*_*gch 65

系统键盘

这个答案告诉我们如何制作一个可以在用户手机上安装的任何应用程序中使用的自定义系统键盘.如果您想制作一个仅在您自己的应用程序中使用的键盘,请参阅我的其他答案.

以下示例如下所示.您可以为任何键盘布局修改它.

在此输入图像描述

以下步骤说明如何创建可用的自定义系统键盘.我尽可能地尝试删除任何不必要的代码.如果您还需要其他功能,我最后会提供更多帮助的链接.

1.启动一个新的Android项目

我将我的项目命名为"自定义键盘".随便打电话给你.这里没有什么特别的.我将离开MainActivity和"Hello World!" 布局原样.

2.添加布局文件

将以下两个文件添加到您应用的res/layout文件夹中:

  • keyboard_view.xml
  • key_preview.xml

keyboard_view.xml

这个视图就像一个容纳我们键盘的容器.在此示例中,只有一个键盘,但您可以添加其他键盘并将其交换进出KeyboardView.

<?xml version="1.0" encoding="utf-8"?>
<android.inputmethodservice.KeyboardView
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/keyboard_view"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:keyPreviewLayout="@layout/key_preview"
    android:layout_alignParentBottom="true">

</android.inputmethodservice.KeyboardView>
Run Code Online (Sandbox Code Playgroud)

key_preview.xml

键预览是按键盘键时弹出的布局.它只显示你正在按下的键(如果你的大指,胖指覆盖它).这不是一个多选弹出窗口.为此,您应该查看候选人视图.

<?xml version="1.0" encoding="utf-8"?>
<TextView
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:gravity="center"
    android:background="@android:color/white"
    android:textColor="@android:color/black"
    android:textSize="30sp">
</TextView>
Run Code Online (Sandbox Code Playgroud)

3.添加支持的xml文件

xml文件夹中创建一个文件res夹.(右键单击res并选择" 新建">"目录".)

然后将以下两个xml文件添加到其中.(右键单击该xml文件夹,然后选择" 新建">"XML资源文件".)

  • number_pad.xml
  • method.xml

number_pad.xml

这是它开始变得更有趣的地方.这Keyboard定义了的布局.

<?xml version="1.0" encoding="utf-8"?>
<Keyboard xmlns:android="http://schemas.android.com/apk/res/android"
    android:keyWidth="20%p"
    android:horizontalGap="5dp"
    android:verticalGap="5dp"
    android:keyHeight="60dp">

    <Row>
        <Key android:codes="49" android:keyLabel="1" android:keyEdgeFlags="left"/>
        <Key android:codes="50" android:keyLabel="2"/>
        <Key android:codes="51" android:keyLabel="3"/>
        <Key android:codes="52" android:keyLabel="4"/>
        <Key android:codes="53" android:keyLabel="5" android:keyEdgeFlags="right"/>
    </Row>

    <Row>
        <Key android:codes="54" android:keyLabel="6" android:keyEdgeFlags="left"/>
        <Key android:codes="55" android:keyLabel="7"/>
        <Key android:codes="56" android:keyLabel="8"/>
        <Key android:codes="57" android:keyLabel="9"/>
        <Key android:codes="48" android:keyLabel="0" android:keyEdgeFlags="right"/>
    </Row>

    <Row>
        <Key android:codes="-5"
             android:keyLabel="DELETE"
             android:keyWidth="40%p"
             android:keyEdgeFlags="left"
             android:isRepeatable="true"/>
        <Key android:codes="10"
             android:keyLabel="ENTER"
             android:keyWidth="60%p"
             android:keyEdgeFlags="right"/>
    </Row>

</Keyboard>
Run Code Online (Sandbox Code Playgroud)

以下是一些需要注意的事项:

  • keyWidth:这是每个键的默认宽度.这20%p意味着每个键应占据p的宽度的20%.但是,它可以被单个键覆盖,正如您可以看到的那样,第三行中的Delete和Enter键发生了.
  • keyHeight:这里是硬编码,但您可以使用类似@dimen/key_height的设置动态设置不同的屏幕尺寸.
  • Gap:水平和垂直间隙表示在键之间留出多少空间.即使你设置它0px仍然有一个小差距.
  • codes:这可以是Unicode或自定义代码值,用于确定按下键时发生的情况或输入的内容.查看keyOutputText是否要输入更长的Unicode字符串.
  • keyLabel:这是键上显示的文本.
  • keyEdgeFlags:这表示密钥应与哪个边对齐.
  • isRepeatable:如果您按住键,它将继续重复输入.

method.xml

该文件告诉系统可用的输入方法子类型.我只是在这里包含一个最小版本.

<?xml version="1.0" encoding="utf-8"?>
<input-method
    xmlns:android="http://schemas.android.com/apk/res/android">

    <subtype
        android:imeSubtypeMode="keyboard"/>

</input-method>
Run Code Online (Sandbox Code Playgroud)

4.添加Java代码以处理键输入

创建一个新的Java文件.我们称之为MyInputMethodService.该文件将所有内容联系在一 它处理从键盘接收的输入并将其发送到接收它的任何视图(EditText例如).

public class MyInputMethodService extends InputMethodService implements KeyboardView.OnKeyboardActionListener {

    @Override
    public View onCreateInputView() {
        // get the KeyboardView and add our Keyboard layout to it
        KeyboardView keyboardView = (KeyboardView) getLayoutInflater().inflate(R.layout.keyboard_view, null);
        Keyboard keyboard = new Keyboard(this, R.xml.number_pad);
        keyboardView.setKeyboard(keyboard);
        keyboardView.setOnKeyboardActionListener(this);
        return keyboardView;
    }

    @Override
    public void onKey(int primaryCode, int[] keyCodes) {

        InputConnection ic = getCurrentInputConnection();
        if (ic == null) return;
        switch (primaryCode) {
            case Keyboard.KEYCODE_DELETE:
                CharSequence selectedText = ic.getSelectedText(0);
                if (TextUtils.isEmpty(selectedText)) {
                    // no selection, so delete previous character
                    ic.deleteSurroundingText(1, 0);
                } else {
                    // delete the selection
                    ic.commitText("", 1);
                }
                break;
            default:
                char code = (char) primaryCode;
                ic.commitText(String.valueOf(code), 1);
        }
    }

    @Override
    public void onPress(int primaryCode) { }

    @Override
    public void onRelease(int primaryCode) { }

    @Override
    public void onText(CharSequence text) { }

    @Override
    public void swipeLeft() { }

    @Override
    public void swipeRight() { }

    @Override
    public void swipeDown() { }

    @Override
    public void swipeUp() { }
}
Run Code Online (Sandbox Code Playgroud)

笔记:

  • OnKeyboardActionListener键盘输入监听.在这个例子中,它还需要所有那些空方法.
  • InputConnection是什么是用于发送输入到像另一种观点EditText.

5.更新清单

我把它放在最后而不是第一,因为它指的是我们上面已经添加的文件.要将自定义键盘注册为系统键盘,您需要serviceAndroidManifest.xml文件中添加一个部分.把它放在application后面的部分activity.

<manifest ...>
    <application ... >
        <activity ... >
            ...
        </activity>

        <service
            android:name=".MyInputMethodService"
            android:label="Keyboard Display Name"
            android:permission="android.permission.BIND_INPUT_METHOD">
            <intent-filter>
                <action android:name="android.view.InputMethod"/>
            </intent-filter>
            <meta-data
                android:name="android.view.im"
                android:resource="@xml/method"/>
        </service>

    </application>
</manifest>
Run Code Online (Sandbox Code Playgroud)

而已!您应该能够立即运行您的应用程序.但是,在设置中启用键盘之前,您不会看到太多内容.

6.在"设置"中启用键盘

每个想要使用键盘的用户都必须在Android设置中启用它.有关如何执行此操作的详细说明,请参阅以下链接:

以下是摘要:

  • 转到Android设置>语言并输入>当前键盘>选择键盘.
  • 您应该在列表中看到自定义键盘.启用它.
  • 返回并再次选择当前键盘.您应该在列表中看到自定义键盘.选择它.

现在,您应该可以在任何可以在Android中输入的键盘使用键盘.

进一步研究

上面的键盘是可用的,但是要创建其他人想要使用的键盘,您可能需要添加更多功能.研究下面的链接,了解如何.

继续

不喜欢标准的KeyboardView外观和行为?我当然不会.看起来自Android 2.0以来它还没有更新.Play商店中的所有自定义键盘怎么样?它们看起来不像上面的丑陋键盘.

好消息是您可以完全自定义键盘的外观和行为.您需要执行以下操作:

  1. 创建自己的子类自定义键盘视图ViewGroup.您可以用Buttons 填充它,甚至可以创建自己的子类自定义键视图View.如果您使用弹出视图,请注意这一点.
  2. 在键盘中添加自定义事件侦听器界面.把它的方法onKeyClicked(String text)称为或者onBackspace().
  3. 你并不需要添加keyboard_view.xml,key_preview.xmlnumber_pad.xml描述了上述指示,因为这些都是为标准KeyboardView.您将在自定义视图中处理所有这些UI方面.
  4. 在您的MyInputMethodService类中,实现您在键盘类中定义的自定义键盘侦听器.这取代了KeyboardView.OnKeyboardActionListener,不再需要.
  5. MyInputMethodService类的onCreateInputView()方法中,创建并返回自定义键盘的实例.不要忘记将键盘的自定义侦听器设置为this.


big*_*nes 31

用途KeyboardView:

KeyboardView kbd = new KeyboardView(context);
kbd.setKeyboard(new Keyboard(this, R.xml.custom));

kbd.setOnKeyboardActionListener(new OnKeyboardActionListener() {
    ....
}
Run Code Online (Sandbox Code Playgroud)

现在你有kbd一个普通的观点.

关于这个的好处是R.xml.custom/res/xml/custom.xml,在xml中定义键盘的布局.有关此文件的更多信息,请查看此处:Keyboard,Keyboard.Row,Keyboard.Key.

  • 我正在使用 KeyboardView 类,但从 API 29 开始,它现已被弃用。 (4认同)

Sur*_*gch 29

应用内键盘

这个答案告诉我们如何使自定义键盘在您的应用程序中独占使用.如果您想制作可在任何应用中使用的系统键盘,请参阅我的其他答案.

示例将如下所示.您可以为任何键盘布局修改它.

在此输入图像描述

1.启动一个新的Android项目

我命名了我的项目InAppKeyboard.无论你想要什么,打电话给你.

2.添加布局文件

键盘布局

将布局文件添加到res/layout文件夹.我打电话给我keyboard.键盘将是我们将从此xml布局文件中膨胀的自定义复合视图.您可以使用您喜欢的任何布局来排列键,但我使用的是LinearLayout.注意merge标签.

RES /布局/ keyboard.xml

<merge xmlns:android="http://schemas.android.com/apk/res/android">

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical">

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="horizontal">

            <Button
                android:id="@+id/button_1"
                android:layout_width="0dp"
                android:layout_height="wrap_content"
                android:layout_weight="1"
                android:text="1"/>

            <Button
                android:id="@+id/button_2"
                android:layout_width="0dp"
                android:layout_height="wrap_content"
                android:layout_weight="1"
                android:text="2"/>

            <Button
                android:id="@+id/button_3"
                android:layout_width="0dp"
                android:layout_height="wrap_content"
                android:layout_weight="1"
                android:text="3"/>

            <Button
                android:id="@+id/button_4"
                android:layout_width="0dp"
                android:layout_height="wrap_content"
                android:layout_weight="1"
                android:text="4"/>

            <Button
                android:id="@+id/button_5"
                android:layout_width="0dp"
                android:layout_height="wrap_content"
                android:layout_weight="1"
                android:text="5"/>

        </LinearLayout>

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="horizontal">

            <Button
                android:id="@+id/button_6"
                android:layout_width="0dp"
                android:layout_height="wrap_content"
                android:layout_weight="1"
                android:text="6"/>

            <Button
                android:id="@+id/button_7"
                android:layout_width="0dp"
                android:layout_height="wrap_content"
                android:layout_weight="1"
                android:text="7"/>

            <Button
                android:id="@+id/button_8"
                android:layout_width="0dp"
                android:layout_height="wrap_content"
                android:layout_weight="1"
                android:text="8"/>

            <Button
                android:id="@+id/button_9"
                android:layout_width="0dp"
                android:layout_height="wrap_content"
                android:layout_weight="1"
                android:text="9"/>

            <Button
                android:id="@+id/button_0"
                android:layout_width="0dp"
                android:layout_height="wrap_content"
                android:layout_weight="1"
                android:text="0"/>

        </LinearLayout>

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="horizontal">

            <Button
                android:id="@+id/button_delete"
                android:layout_width="0dp"
                android:layout_height="wrap_content"
                android:layout_weight="2"
                android:text="Delete"/>

            <Button
                android:id="@+id/button_enter"
                android:layout_width="0dp"
                android:layout_height="wrap_content"
                android:layout_weight="3"
                android:text="Enter"/>

        </LinearLayout>
    </LinearLayout>

</merge>
Run Code Online (Sandbox Code Playgroud)

活动布局

出于演示目的,我们的活动只有一个EditText,键盘位于底部.我打电话给自定义键盘视图MyKeyboard.(我们将很快添加此代码,因此暂时忽略该错误.)将所有键盘代码放入单个视图中的好处是,它可以轻松地在其他活动或应用程序中重用.

RES /布局/ activity_main.xml中

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="com.example.inappkeyboard.MainActivity">

    <EditText
        android:id="@+id/editText"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:background="#c9c9f1"
        android:layout_margin="50dp"
        android:padding="5dp"
        android:layout_alignParentTop="true"/>

    <com.example.inappkeyboard.MyKeyboard
        android:id="@+id/keyboard"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical"
        android:layout_alignParentBottom="true"/>

</RelativeLayout>
Run Code Online (Sandbox Code Playgroud)

3.添加Keyboard Java文件

添加新的Java文件.我打电话给我MyKeyboard.

这里要注意的最重要的事情是没有硬链接到任何EditTextActivity.这样可以轻松地将其插入任何需要它的应用程序或活动中.这个自定义键盘视图也使用了一个InputConnection模拟系统键盘与之通信的方式EditText.这就是我们如何避免硬链接.

MyKeyboard 是一个复合视图,它膨胀了我们在上面定义的视图布局.

MyKeyboard.java

public class MyKeyboard extends LinearLayout implements View.OnClickListener {

    // constructors
    public MyKeyboard(Context context) {
        this(context, null, 0);
    }

    public MyKeyboard(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public MyKeyboard(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init(context, attrs);
    }

    // keyboard keys (buttons)
    private Button mButton1;
    private Button mButton2;
    private Button mButton3;
    private Button mButton4;
    private Button mButton5;
    private Button mButton6;
    private Button mButton7;
    private Button mButton8;
    private Button mButton9;
    private Button mButton0;
    private Button mButtonDelete;
    private Button mButtonEnter;

    // This will map the button resource id to the String value that we want to 
    // input when that button is clicked.
    SparseArray<String> keyValues = new SparseArray<>();

    // Our communication link to the EditText
    InputConnection inputConnection;

    private void init(Context context, AttributeSet attrs) {

        // initialize buttons
        LayoutInflater.from(context).inflate(R.layout.keyboard, this, true);
        mButton1 = (Button) findViewById(R.id.button_1);
        mButton2 = (Button) findViewById(R.id.button_2);
        mButton3 = (Button) findViewById(R.id.button_3);
        mButton4 = (Button) findViewById(R.id.button_4);
        mButton5 = (Button) findViewById(R.id.button_5);
        mButton6 = (Button) findViewById(R.id.button_6);
        mButton7 = (Button) findViewById(R.id.button_7);
        mButton8 = (Button) findViewById(R.id.button_8);
        mButton9 = (Button) findViewById(R.id.button_9);
        mButton0 = (Button) findViewById(R.id.button_0);
        mButtonDelete = (Button) findViewById(R.id.button_delete);
        mButtonEnter = (Button) findViewById(R.id.button_enter);

        // set button click listeners
        mButton1.setOnClickListener(this);
        mButton2.setOnClickListener(this);
        mButton3.setOnClickListener(this);
        mButton4.setOnClickListener(this);
        mButton5.setOnClickListener(this);
        mButton6.setOnClickListener(this);
        mButton7.setOnClickListener(this);
        mButton8.setOnClickListener(this);
        mButton9.setOnClickListener(this);
        mButton0.setOnClickListener(this);
        mButtonDelete.setOnClickListener(this);
        mButtonEnter.setOnClickListener(this);

        // map buttons IDs to input strings
        keyValues.put(R.id.button_1, "1");
        keyValues.put(R.id.button_2, "2");
        keyValues.put(R.id.button_3, "3");
        keyValues.put(R.id.button_4, "4");
        keyValues.put(R.id.button_5, "5");
        keyValues.put(R.id.button_6, "6");
        keyValues.put(R.id.button_7, "7");
        keyValues.put(R.id.button_8, "8");
        keyValues.put(R.id.button_9, "9");
        keyValues.put(R.id.button_0, "0");
        keyValues.put(R.id.button_enter, "\n");
    }

    @Override
    public void onClick(View v) {

        // do nothing if the InputConnection has not been set yet
        if (inputConnection == null) return;

        // Delete text or input key value
        // All communication goes through the InputConnection
        if (v.getId() == R.id.button_delete) {
            CharSequence selectedText = inputConnection.getSelectedText(0);
            if (TextUtils.isEmpty(selectedText)) {
                // no selection, so delete previous character
                inputConnection.deleteSurroundingText(1, 0);
            } else {
                // delete the selection
                inputConnection.commitText("", 1);
            }
        } else {
            String value = keyValues.get(v.getId());
            inputConnection.commitText(value, 1);
        }
    }

    // The activity (or some parent or controller) must give us 
    // a reference to the current EditText's InputConnection
    public void setInputConnection(InputConnection ic) {
        this.inputConnection = ic;
    }
}
Run Code Online (Sandbox Code Playgroud)

4.将键盘指向EditText

对于系统键盘,Android使用InputMethodManager将键盘指向焦点EditText.在此示例中,活动将通过提供从EditText我们的自定义键盘到的链接来取代它.

由于我们没有使用系统键盘,我们需要禁用它以防止它在触摸时弹出EditText.其次,我们需要得到InputConnection来自EditText和它给我们的键盘.

MainActivity.java

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        EditText editText = (EditText) findViewById(R.id.editText);
        MyKeyboard keyboard = (MyKeyboard) findViewById(R.id.keyboard);

        // prevent system keyboard from appearing when EditText is tapped
        editText.setRawInputType(InputType.TYPE_CLASS_TEXT);
        editText.setTextIsSelectable(true);

        // pass the InputConnection from the EditText to the keyboard
        InputConnection ic = editText.onCreateInputConnection(new EditorInfo());
        keyboard.setInputConnection(ic);
    }
}
Run Code Online (Sandbox Code Playgroud)

如果您的Activity有多个EditTexts,那么您需要编写代码以将正确的EditText传递InputConnection给键盘.(您可以通过向EditTexts 添加OnFocusChangeListenerOnClickListener来执行此操作.请参阅此文章以进行讨论.)您可能还希望在适当的时间隐藏或显示键盘.

成品

而已.您应该能够立即运行示例应用程序并根据需要输入或删除文本.您的下一步是修改所有内容以满足您自己的需求.例如,在我的一些键盘中,我使用了TextViews而不是Buttons,因为它更容易定制它们.

笔记

  • 在xml布局文件中,如果要使键看起来更好,也可以使用a TextView而不是a Button.然后只需使背景成为可绘制的,可在按下时更改外观状态.
  • 高级自定义键盘:为了在键盘外观和键盘切换方面提供更大的灵活性,我现在正在创建子类View和自定义键盘子类的自定义键视图ViewGroup.键盘以编程方式显示所有键.密钥使用接口与键盘通信(类似于片段与活动的通信方式).如果您只需要一个键盘布局,则不需要这样做,因为xml布局可以正常工作.但是如果你想看一个我一直在做的事情的例子,请查看这里的所有Key*Keyboard*类.请注意,我还使用容器视图,其功能是将键盘交换进出.

  • “点击 EditText 时防止系统键盘出现”不起作用,系统键盘仍然弹出。`editText.setShowSoftInputOnFocus(false);` 现在可以使用 (3认同)
  • @MarekTakac,您需要禁用系统键盘并在每个活动中添加自定义键盘。如果一个 Activity 有多个 `EditText`,那么你需要给它们添加一个 `onFocusChangedListener`,这样当它们获得焦点时,你可以将当前 `EditText` 中的 `InputConnection` 分配给你的自定义键盘。 (2认同)

nit*_*ddy 14

这是一个软键盘的示例项目.

https://developer.android.com/guide/topics/text/creating-input-method.html

你的应该采用不同的布局.

编辑:如果您只需要在您的应用程序中使用键盘,它非常简单!创建具有垂直方向的线性布局,并在其内部以水平方向创建3个线性布局.然后将每行的按钮放在每个水平线性布局中,并将权重属性分配给按钮.对所有这些使用android:layout_weight = 1,所以它们间隔相等.

这将解决.如果您没有得到预期的结果,请在此处发布代码,我们随时为您提供帮助!


You*_*jae 7

我发现的最好的文档示例之一.

http://www.fampennings.nl/maarten/android/09keyboard/index.htm

KeyboardView 提供了相关的XML文件和源代码.


Don*_*ody 6

我最近在尝试决定使用什么方法来创建我自己的自定义键盘时遇到了这篇文章。我发现 Android 系统 API 非常有限,所以我决定制作自己的应用内键盘。使用Suragch 的答案作为我研究的基础,我继续设计我自己的键盘组件。它以 MIT 许可证发布在 GitHub 上。希望这会为其他人节省大量时间和头痛。

该架构非常灵活。有一个主视图 (CustomKeyboardView),您可以将其注入任何您想要的键盘布局和控制器。

您只需要在您的活动 xml 中声明 CustomKeyboardView(您也可以以编程方式进行):

    <com.donbrody.customkeyboard.components.keyboard.CustomKeyboardView
    android:id="@+id/customKeyboardView"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_alignParentBottom="true" />
Run Code Online (Sandbox Code Playgroud)

然后用它注册你的 EditText 并告诉它他们应该使用什么类型的键盘:

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContentView(R.layout.activity_main)

    val numberField: EditText = findViewById(R.id.testNumberField)
    val numberDecimalField: EditText = findViewById(R.id.testNumberDecimalField)
    val qwertyField: EditText = findViewById(R.id.testQwertyField)

    keyboard = findViewById(R.id.customKeyboardView)
    keyboard.registerEditText(CustomKeyboardView.KeyboardType.NUMBER, numberField)
    keyboard.registerEditText(CustomKeyboardView.KeyboardType.NUMBER_DECIMAL, numberDecimalField)
    keyboard.registerEditText(CustomKeyboardView.KeyboardType.QWERTY, qwertyField)
}
Run Code Online (Sandbox Code Playgroud)

CustomKeyboardView 处理剩下的事情!

我已经使用 Number、NumberDecimal 和 QWERTY 键盘进行了操作。随意下载它并创建自己的布局和控制器。它看起来像这样:

android自定义键盘gif风景

在此处输入图片说明

即使这不是您决定采用的架构,但希望查看有效的应用程序内键盘的源代码会有所帮助。

同样,这里是项目的链接:自定义应用内键盘

编辑:我不再是 Android 开发人员,也不再维护这个 GitHub 项目。在这一点上可能有更现代的方法和架构,但如果您愿意,请随时参考 GitHub 项目并对其进行分叉。