如何在Android中制作自定义键盘?[关闭]

wn9m85ua  于 2022-12-25  发布在  Android
关注(0)|答案(9)|浏览(183)
    • 已关闭**。此问题需要超过focused。当前不接受答案。
    • 想要改进此问题吗?**更新此问题,使其仅关注editing this post的一个问题。

10个月前关闭。
社区在10个月前审查了是否重新讨论这个问题,并将其关闭:
原始关闭原因未解决
Improve this question
我想做一个自定义键盘,我不知道怎么用XML和Java来做,下图是我想做的键盘模型,只需要数字。

tvz2xvvm

tvz2xvvm1#

系统键盘

这个答案告诉你如何制作一个自定义系统键盘,可以在用户安装在手机上的任何应用程序中使用。如果你想制作一个键盘,只在你自己的应用程序中使用,那么see my other answer
下面的例子看起来像这样。你可以修改它以适应任何键盘布局。

下面的步骤展示了如何创建一个自定义系统键盘。我尽可能地删除了不必要的代码。如果您还需要其他功能,我在最后提供了更多帮助的链接。

1.开始一个新的Android项目

我将我的项目命名为"自定义键盘"。随你怎么称呼它。这里没有其他特别的东西。我将只保留MainActivity和"Hello World!"的布局。

2.添加布局文件

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

  • keyboard_view.xml
  • key_preview.xml
    • 键盘视图. 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>
    • 密钥预览. 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>

3.添加支持xml文件

res文件夹中创建一个xml文件夹(右键单击res并选择新建〉目录)。
然后将下面两个xml文件添加到其中(右键单击xml文件夹并选择New〉XML资源文件)。

  • number_pad.xml
  • method.xml
    • 数字键盘. xml**

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

<?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>

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

  • keyWidth:这是每个键的默认宽度。20%p意味着每个键应该占parent宽度的20%。但是,它可以被单独的键覆盖,正如您在第三行中看到的Delete和Enter键所发生的情况。
  • keyHeight:这里是硬编码的,但是您可以使用@dimen/key_height之类的东西来针对不同的屏幕大小动态地设置它。
  • Gap:水平和垂直间隙告诉键之间留有多少空间。即使你把它设置为0px,仍然有一个很小的间隙。
  • codes:这可以是Unicode或自定义代码值,用于确定按键时发生的操作或输入的内容。如果要输入更长的Unicode字符串,请参阅keyOutputText
  • keyLabel:这是键上显示的文本。
  • keyEdgeFlags:这表示关键点应与哪个边对齐。
  • isRepeatable:如果你按住键,它会不断重复输入。
    • 方法. 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>

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() { }
}

注:

  • OnKeyboardActionListener监听键盘输入,它还需要本例中所有的空方法。
  • InputConnection用于将输入发送到另一个视图(如EditText)。

5.更新清单

我把它放在最后而不是最前面,因为它引用了我们上面已经添加的文件。要将您的自定义键盘注册为系统键盘,您需要在 * AndroidManifest. xml * 文件中添加一个service部分。将它放在activity之后的application部分中。

<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>

就是这样!你现在应该可以运行你的应用了。但是,在设置中启用键盘之前,你不会看到太多内容。

6.在设置中启用键盘

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

以下是总结:

  • 前往Android设置〉语言和输入法〉当前键盘〉选择键盘。
  • 您应该在列表中看到您的自定义键盘。启用它。
  • 返回并再次选择"当前键盘"。您应该在列表中看到您的"自定义键盘"。选择它。

现在你应该可以在Android中任何可以打字的地方使用键盘了。

进一步研究

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

∮继续∮
不喜欢标准的KeyboardView的外观和行为吗?我当然不喜欢。它看起来像是从Android 2.0开始就没有更新过。Play商店里的那些自定义键盘怎么样?它们看起来一点也不像上面丑陋的键盘。

好消息是您可以完全自定义自己的键盘外观和行为。您需要做以下事情:
1.创建你自己的ViewGroup子类的自定义键盘视图。你可以用Button填充它,甚至可以创建你自己的View子类的自定义键视图。如果你使用弹出视图,那么note this
1.在你的键盘上添加一个custom event listener接口,调用它的方法来处理onKeyClicked(String text)或者onBackspace()之类的事情。
1.您不需要添加上面描述的keyboard_view.xmlkey_preview.xmlnumber_pad.xml,因为这些都是针对标准KeyboardView的,您将在自定义视图中处理所有这些UI方面。
1.在MyInputMethodService类中,实现在keyboard类中定义的自定义键盘侦听器,以取代不再需要的KeyboardView.OnKeyboardActionListener
1.在MyInputMethodService类的onCreateInputView()方法中,创建并返回自定义键盘的示例。不要忘记将键盘的自定义侦听器设置为this

vvppvyoh

vvppvyoh2#

首先,您需要一个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>
    • 请注意,您必须创建backspace可绘制对象,并将其以非常小的尺寸(如18x18像素)放置在res/drawable-ldpi文件夹中

然后在您希望使用它的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>
    • 请注意,要放置android.inputmethodservice.KeyboardView的xml文件必须为RelativeLayout,以便能够设置alignParentBottom="true"(通常键盘显示在屏幕底部)

然后,您需要在ActivityonCreate函数中添加以下代码,该函数处理要将键盘连接到的TextView

// 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);
    • 请注意,mKeyboardmKeyboardView是必须创建的私有类变量。

然后需要以下函数来打开键盘(必须通过onClick xml属性将其与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);
    }

最后,您需要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() {
    }
};

大多数代码找到here
____________________________________________________________-

    • 编辑:**

由于KeyboardView自API级别29起就已过时,因此您可以在this website中找到它的代码,并在代码中创建一个类,然后再按上述方式实现键盘。

jvidinwx

jvidinwx3#

应用程序内键盘

这个答案告诉你如何制作一个专门在你的应用中使用的自定义键盘。如果你想制作一个可以在任何应用中使用的系统键盘,那么see my other answer
这个例子看起来像这样,你可以修改它来适应任何键盘布局。

1.开始一个新的Android项目

我把我的项目命名为InAppKeyboard。你想怎么命名都行。

2.添加布局文件

    • 键盘布局**

添加一个布局文件到res/layout文件夹。我叫我的keyboard。键盘将是一个自定义的复合视图,我们将从这个xml布局文件膨胀。你可以使用任何你喜欢的布局来安排键,但我使用的是LinearLayout。注意merge标签。

  • res/布局/键盘. 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>
    • 活动布局**

出于演示目的,我们的Activity只有一个EditText,键盘位于底部。我将我的自定义键盘视图命名为MyKeyboard。(我们很快就会添加此代码,所以现在忽略此错误。)将所有键盘代码放在一个视图中的好处是,它可以方便地在其他Activity或应用中重用。

  • 资源/布局/活动_主. 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>

3.添加键盘Java文件

添加一个新的Java文件。我把我的命名为MyKeyboard
这里需要注意的最重要的一点是,没有任何EditTextActivity的硬链接。这使得它很容易插入到任何需要它的应用或Activity中。这个自定义键盘视图还使用了InputConnection,它模仿了系统键盘与EditText通信的方式。这就是我们如何避免硬链接的。
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;
    }
}

4.将键盘指向EditText

对于系统键盘,Android使用InputMethodManager将键盘指向焦点EditText。在本例中,Activity将通过提供从EditText到我们的自定义键盘的链接来代替。
由于我们没有使用系统键盘,我们需要禁用它,以防止它在我们触摸EditText时弹出。其次,我们需要从EditText获取InputConnection并将其提供给我们的键盘。

  • 主要活动. 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);
    }
}

如果您的Activity有多个EditText,那么您需要编写代码来将右侧EditText的InputConnection传递给键盘。(您可以通过向EditText添加OnFocusChangeListenerOnClickListener来完成此操作。有关此操作的讨论,请参阅this article。)您可能还需要在适当的时候隐藏或显示键盘。

完成

就是这样。你现在应该可以运行示例应用程序,并根据需要输入或删除文本。下一步是修改所有内容以满足自己的需要。例如,在我的一些键盘中,我使用TextView而不是Button,因为它更容易自定义。

注解

  • 在xml布局文件中,如果你想让按键看起来更好的话,你也可以使用TextView而不是Button,然后把背景做成一个可绘制的,当按下按键时,它会改变外观状态。
  • 高级自定义键盘:对于键盘外观和键盘切换的更多灵活性,我现在正在创建子类为View的自定义键视图和子类为ViewGroup的自定义键盘,键盘以编程方式布局所有键,键使用接口与键盘通信(类似于片段如何与活动通信)。如果您只需要单个键盘布局,这是不必要的,因为XML布局可以很好地工作。但是如果你想看看我一直在做的事情的例子,请查看所有的Key*Keyboard*here,注意我还使用了一个容器视图,它的功能是交换键盘。
lrl1mhuk

lrl1mhuk4#

使用KeyboardView

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

kbd.setOnKeyboardActionListener(new OnKeyboardActionListener() {
    ....
}

现在您有了kbd,这是一个普通视图。
这样做的好处是R.xml.custom引用了/res/xml/custom.xml/res/xml/custom.xml在xml中定义了键盘的布局。一对一对一,一对二对一,一对三对一。

cclgggtu

cclgggtu5#

下面是一个软键盘的示例项目。
https://developer.android.com/guide/topics/text/creating-input-method.html
您的应该在同一行中,但布局不同。
编辑:如果你只需要在你的应用中使用键盘,那就非常简单了!创建一个垂直方向的线性布局,并在其中创建3个水平方向的线性布局。然后将每行的按钮放置在每个水平线性布局中,并为按钮分配weight属性。对所有按钮使用android:layout_weight=1,这样它们的间距就相等了。
这将解决。如果你没有得到什么是预期的,请张贴代码在这里,我们在这里帮助你!

n53p2ov0

n53p2ov06#

这是我找到的最好的有据可查的例子之一。
http://www.fampennings.nl/maarten/android/09keyboard/index.htm
提供了KeyboardView相关的XML文件和源代码。

ubbxdtey

ubbxdtey7#

最近,当我在考虑用什么方法来创建自己的自定义键盘时,我看到了这篇文章。我发现Android系统API非常有限,所以我决定制作自己的应用内键盘。以Suragch的答案作为我研究的基础。我接着设计了my own keyboard component,它被贴在GitHub上,有MIT的许可证,希望这能保存别人很多时间和头痛。
架构相当灵活。有一个主视图(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" />

然后向它注册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)
}

CustomKeyboardView处理其余的工作!
我已经开始使用数字、数字十进制和QWERTY键盘了。欢迎下载并创建自己的布局和控制器。它看起来像这样:

即使这不是您决定使用的架构,希望它能帮助您查看一个工作的应用程序内键盘的源代码。
同样,这里是该项目的链接:Custom In-App Keyboard

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

2admgd59

2admgd598#

Suragch给出了目前为止最好的答案,但他跳过了某些对编译应用程序很重要的次要内容。
我希望通过改进苏拉奇的答案来做出一个比他更好的答案。我将添加所有他没有添加的缺失元素。
我使用安卓应用APK Builder 1.1.0编译了我的APK。现在我们开始吧。
要构建一个Android应用程序,我们需要几个文件和文件夹,这些文件和文件夹以某种格式组织并相应地大写。
res layout -〉xml文件描述应用程序在手机上的外观。类似于html如何塑造网页在浏览器上的外观。允许您的应用程序相应地适合屏幕。
values -〉常量数据,如colors.xml、strings.xml、styles.xml。这些文件必须正确拼写。
可绘制-〉图片{jpeg,png,...};随便说什么。
mipmap -〉更多图片。用于应用程序图标?
xml -〉更多的xml文件。
src -〉的作用类似于html中的JavaScript。layout文件将初始化启动视图,而您的java文件将动态控制标记元素和触发事件。事件也可以像html一样直接在layout.xml中激活。
这个文件记录了你的应用程序是关于什么的。应用程序名,程序类型,需要的权限等等。这似乎使Android相当安全。程序不能做他们在清单中没有要求的事情。
现在Android程序有4种类型,一个活动,一个服务,一个内容提供商,一个广播接收器。我们的键盘将是一个服务,允许它在后台运行,它不会出现在要启动的应用列表中;但是它可以被卸载。
要编译你的应用,需要Gradle和APK签名。你可以研究一下,也可以使用Android版APK Builder。这非常简单。
现在我们已经了解了Android开发,接下来让我们创建文件和文件夹。

  • 按照我上面讨论的方法创建文件和文件夹。我的目录将如下所示:
  • 数字键盘
  • AndroidManifest.xml
  • 来源
  • 萨拉奇
  • 数字填充
  • MyInputMethodService.java
  • 雷斯
  • 可拉伸的
  • Suragch_NumPad_icon.png
  • 版面设计
  • key_preview.xml
  • keyboard_view.xml
  • XML语言
  • method.xml
  • number_pad.xml
  • 价值观
  • colors.xml
  • strings.xml
  • styles.xml

请记住,如果您使用的是IDE,如Android Studio,它可能有一个项目文件。
1.写文件。
答:数字键盘/资源/布局/键_预览. 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>

B:数字键盘/资源/布局/键盘_视图. xml

<?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>

C:数字键盘/资源/xml/方法. 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>

D:数字键盘/资源/xml/数字键盘. xml

<?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>

当然,这可以很容易地编辑到您喜欢的。您甚至可以使用图像,而不是lf的话为标签。
Suragch没有演示values文件夹中的文件,并假设我们可以访问Android Studio;它会自动创建它们。好在我有APK Builder。
E:数字键盘/资源/值/颜色. xml

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <color name="colorPrimary">#3F51B5</color>
    <color name="colorPrimaryDark">#303F9F</color>
    <color name="colorAccent">#FF4081</color>
</resources>

F:数字键盘/资源/值/字符串. xml

<resources>
    <string name="app_name">Suragch NumPad</string>
</resources>

G:数字键盘/资源/值/样式. xml

<resources>

    <!-- Base application theme. -->
    <style name="AppTheme" parent="android:Theme.Material.Light.DarkActionBar">
        <!-- Customize your theme here. -->
    </style>

</resources>

H:数字键盘/安卓清单. xml
这是一个真正需要竞争的文件。在这里,我觉得我永远不会编译我的程序。sob. sob。如果你检查Suracgh的回答,你会看到他把第一组字段留空,并在这个文件中添加了activity标签。正如我所说,有四种类型的Android程序。activity是一个带有启动器图标的常规应用程序。这个numpad不是一个activity!而且他没有实现任何activity。
我的朋友没有包含activity标签。你的程序会编译,当你试图启动它时会崩溃!我帮不了你。如果我的设置能用的话就试试吧。
正如你所看到的,有一个服务标签,它将它注册为一个服务。另外,service.android:name必须是java文件中扩展服务的公共类的名称。它必须相应地大写。package也是我们在java文件中声明的包的名称。

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="Saragch.num_pad">

    <uses-sdk
        android:minSdkVersion="12"
        android:targetSdkVersion="27" />

    <application
        android:allowBackup="true"
        android:icon="@drawable/Suragch_NumPad_icon"
        android:label="@string/app_name"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">

        <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>

I:数字键盘/源代码/Saragch/数字键盘/MyInputMethodService.java
注意:我认为java是src的替代品。
这是另一个有问题的文件,但没有manifest文件那么有争议。因为我对Java足够了解,知道什么是什么,什么不是。我几乎不知道xml以及它如何与Android开发联系在一起!
这里的问题是他没有导入任何东西!我的意思是,他给了我们一个“完整”的文件,其中使用的名称无法解析!InputMethodService,键盘等。这是不好的做法先生Suragch。谢谢你帮助我,但如果名称无法解析,你希望代码如何编译?
以下是正确编辑的版本。我只是碰巧扑向几个提示,驱使我到正确的地方,以了解到底要导入什么。

package Saragch.num_pad;

import android.inputmethodservice.InputMethodService;
import android.inputmethodservice.KeyboardView;
import android.inputmethodservice.Keyboard;

import android.text.TextUtils;
import android.view.inputmethod.InputConnection;

import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.os.Build;
import android.os.Bundle;
import android.view.View;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;

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);
            }

            ic.deleteSurroundingText(1, 0);
            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() { }
}

1.编译并签署您的项目。
这就是我作为一个纽比Android开发人员一无所知的地方。我想手动学习它,因为我相信真实的的程序员可以手动编译。
我认为gradle是编译和打包到apk的工具之一。apk看起来像一个jar文件或一个rar的zip文件。然后有两种类型的签名。debug密钥,这是不允许的播放存储和私钥。
好吧,让我们给予萨拉奇先生一把。谢谢你看我的视频。比如,订阅。

k0pti3hp

k0pti3hp9#

有同样的问题。我用表格布局在第一次,但布局不断变化后,按下按钮。发现这个页面非常有用虽然。http://mobile.tutsplus.com/tutorials/android/android-user-interface-design-creating-a-numeric-keypad-with-gridlayout/

相关问题