Android 自定义软键盘(Android Studio)

Android custom soft keyboard (Android Studio)

我正在尝试创建一个包含多个活动的应用程序来监控用户与设备交互的不同方面。主要方面之一是来自自定义键盘的文本输入。我在网上看过几个不同的例子,但 none 似乎对我来说工作正常。不幸的是,当我尝试在 activity 中显示键盘时,它看起来像这样:http://puu.sh/jHQFQ/123ddd742b.jpg。老实说,我不知道为什么会这样。

这是我的键盘:`

<?xml version="1.0" encoding="utf-8"?>
<Keyboard xmlns:android="http://schemas.android.com/apk/res/android">
    android:keyWidth="10%p"
    android:verticalGap="0px"
    android:horizontalGap="0px"

    <Row>
        <Key android:codes="113" android:keyLabel="q" android:keyEdgeFlags="left"/>
        <Key android:codes="119" android:keyLabel="w"/>
        <Key android:codes="101" android:keyLabel="e"/>
        <Key android:codes="114" android:keyLabel="r"/>
        <Key android:codes="116" android:keyLabel="t"/>
        <Key android:codes="121" android:keyLabel="y"/>
        <Key android:codes="117" android:keyLabel="u"/>
        <Key android:codes="105" android:keyLabel="i"/>
        <Key android:codes="111" android:keyLabel="o"/>
        <Key android:codes="112" android:keyLabel="p" android:keyEdgeFlags="right"/>
    </Row>

    <Row>
        <Key android:codes="97" android:keyLabel="a" android:horizontalGap="5%p" android:keyEdgeFlags="left"/>
        <Key android:codes="115" android:keyLabel="s"/>
        <Key android:codes="100" android:keyLabel="d"/>
        <Key android:codes="102" android:keyLabel="f"/>
        <Key android:codes="103" android:keyLabel="g"/>
        <Key android:codes="104" android:keyLabel="h"/>
        <Key android:codes="106" android:keyLabel="j"/>
        <Key android:codes="107" android:keyLabel="k"/>
        <Key android:codes="108" android:keyLabel="l" android:horizontalGap="5%p" android:keyEdgeFlags="right"/>
    </Row>

    <Row>
        <Key android:codes="-1" android:keyLabel="\u21E7" android:keyWidth="15%p" android:isModifier="true" android:isSticky="true" android:keyEdgeFlags="left"/>
        <Key android:codes="122" android:keyLabel="z"/>
        <Key android:codes="120" android:keyLabel="x"/>
        <Key android:codes="99" android:keyLabel="c"/>
        <Key android:codes="118" android:keyLabel="v"/>
        <Key android:codes="98" android:keyLabel="b"/>
        <Key android:codes="110" android:keyLabel="n"/>
        <Key android:codes="109" android:keyLabel="m"/>
        <Key android:codes="-5" android:keyLabel="\u232B" android:keyWidth="15%p" android:keyEdgeFlags="right" android:isRepeatable="true"/>
    </Row>

    <Row android:rowEdgeFlags="bottom">
        <Key android:codes="-4" android:keyLabel="\u2328" android:keyWidth="20%p" android:keyEdgeFlags="left"/>
        <Key android:codes="44" android:keyLabel="," android:keyWidth="15%p"/>
        <Key android:codes="32" android:keyLabel="\u2334" android:keyWidth="30%p" android:isRepeatable="true"/>
        <Key android:codes="46" android:keyLabel="." android:keyWidth="15%p"/>
        <Key android:codes="13" android:keyLabel="\u21B5" android:keyWidth="20%p" android:keyEdgeFlags="right"/>
    </Row>
</Keyboard>

Here is my layout:

<?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" android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    android:paddingBottom="@dimen/activity_vertical_margin"
    tools:context="com.scsu.compsci.securityapp.Mod1_1">

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

    <EditText
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:inputType="textNoSuggestions|textImeMultiLine"
        android:ems="10"
        android:id="@+id/userInput"
        android:layout_alignParentTop="true"
        android:layout_alignParentLeft="true"
        android:layout_alignParentStart="true"
        android:layout_alignParentRight="true"
        android:layout_alignParentEnd="true"
        android:layout_marginLeft="40dp"
        android:layout_marginStart="40dp"
        android:layout_marginTop="150dp"
        android:layout_marginRight="40dp"
        android:layout_marginEnd="40dp"
        android:onClick="toggleKeyboard" />

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:textAppearance="?android:attr/textAppearanceMedium"
        android:text="@string/question"
        android:id="@+id/textView"
        android:layout_alignParentTop="true"
        android:layout_centerHorizontal="true"
        android:layout_marginTop="75dp"/>

    <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="@string/next_button"
        android:id="@+id/nextMod1"
        android:layout_alignParentBottom="true"
        android:layout_centerHorizontal="true"
        android:layout_marginBottom="50dp"
        android:onClick="mod5"
        android:textStyle="normal"
        android:typeface="normal"
        android:enabled="true"
        android:visibility="gone" />

    <requestFocus
        android:layout_alignParentTop="true"
        android:layout_alignLeft="@+id/textView"
        android:layout_alignStart="@+id/textView"
        android:layout_marginTop="581dp" />

</RelativeLayout>

And here is the Java file:

package com.scsu.compsci.securityapp;

import android.app.Activity;
import android.app.AlertDialog;
import android.content.Intent;
import android.inputmethodservice.Keyboard;
import android.inputmethodservice.KeyboardView;
import android.os.Bundle;
import android.view.KeyEvent;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.inputmethod.InputMethodManager;
import android.widget.Button;
import android.widget.EditText;

import java.util.ArrayList;

public class Mod1_1 extends Activity implements View.OnKeyListener, KeyboardView.OnKeyboardActionListener {

    EditText enterText;
    AlertDialog alert;
    Button next;
    Keyboard keys;
    KeyboardView keysView;
    boolean shift;
    long timeDown;
    long timeUp;
    long timeHold;
    long timeInterval;
    public static ArrayList<ArrayList<String>> module1_1;
    public static ArrayList<String> keyDown;
    public static ArrayList<String> keyUp;
    public static ArrayList<String> keyHold;
    public static ArrayList<String> keyInterval;
    public static ArrayList<String> keySequence;
    public static ArrayList<String> tapSize;
    public static ArrayList<String> tapPressure;

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

        enterText = (EditText) findViewById(R.id.userInput);
        next = (Button) findViewById(R.id.nextMod1);
        shift = false;

        module1_1 = new ArrayList<ArrayList<String>>();
        keyDown = new ArrayList<String>();
        keyUp = new ArrayList<String>();
        keyHold = new ArrayList<String>();
        keyInterval = new ArrayList<String>();
        keySequence = new ArrayList<String>();
        tapSize = new ArrayList<String>();
        tapPressure = new ArrayList<String>();

        // Create the keyboard
        keys = new Keyboard(this, R.xml.keyboard);
        keysView = (KeyboardView) findViewById(R.id.keyboard);
        keysView.setKeyboard(keys);
        keysView.setPreviewEnabled(false);
        keysView.setOnKeyListener(this);
        keysView.setOnKeyboardActionListener(this);
        keysView.bringToFront();
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.menu_mod1_1, menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        // Handle action bar item clicks here. The action bar will
        // automatically handle clicks on the Home/Up button, so long
        // as you specify a parent activity in AndroidManifest.xml.
        int id = item.getItemId();

        //noinspection SimplifiableIfStatement
        if (id == R.id.action_settings) {
            return true;
        }

        return super.onOptionsItemSelected(item);
    }

    @Override
    public boolean onKey(View v, int keyCode, KeyEvent event) {
        return false;
    }

    @Override
    public void onPress(int primaryCode) {
        timeDown = System.nanoTime();
        timeHold = System.nanoTime();
//        timeInterval = System.nanoTime() - timeInterval;
        if (timeInterval != 0)
            keyInterval.add(Long.toString(System.nanoTime() - timeInterval));
    }

    @Override
    public void onRelease(int primaryCode) {
//        timeUp = System.nanoTime() - timeUp;
        keyUp.add(Long.toString(System.nanoTime() - timeUp));
//        timeHold = System.nanoTime() - timeHold;
        keyHold.add(Long.toString(System.nanoTime() - timeHold));
        timeInterval = System.nanoTime();
    }

    @Override
    public void onKey(int primaryCode, int[] keyCodes) {
//        timeDown = System.nanoTime() - timeDown;
        keyDown.add(Long.toString(System.nanoTime() - timeDown));
        timeUp = System.nanoTime();
        keySequence.add(Integer.toString(primaryCode));

        switch(primaryCode) {
            case -1:
                shift = !shift;
                keys.setShifted(shift);
                keysView.invalidateAllKeys();
                break;
            case -4:
                keysView.setVisibility(View.GONE);
                keysView.setEnabled(false);
                next.setVisibility(View.GONE);
                break;
            default:
                char c = (char) primaryCode;
                if (Character.isLetter(c) && shift)
                    c = Character.toUpperCase(c);
                enterText.append(Character.toString(c));
        }
    }

    @Override
    public void onText(CharSequence text) {

    }

    @Override
    public void swipeLeft() {

    }

    @Override
    public void swipeRight() {

    }

    @Override
    public void swipeDown() {

    }

    @Override
    public void swipeUp() {

    }

    public void toggleKeyboard(View view) {
        keysView.setVisibility(View.VISIBLE);
        keysView.setEnabled(true);
        if (view != null)
            ((InputMethodManager) getSystemService(Activity.INPUT_METHOD_SERVICE)).hideSoftInputFromWindow(view.getWindowToken(), 0);
    }

    public void mod5(View view) {
        module1_1.add(0, keyDown);
        module1_1.add(1, keyUp);
        module1_1.add(2, keyHold);
        module1_1.add(3, keyInterval);
        module1_1.add(4, keySequence);
//        module1.add(5, tapSize);
//        module1.add(6, tapPressure);
        MainActivity.user.add(1, module1_1);
        // create Mod1_2
        Intent intent = new Intent(this, Mod5.class);
        startActivity(intent);
    }
}

` 我有三星 Galaxy S5 运行 5.0 (Lollipop)。请记住,我只做了一年的程序员,我在 3 个月前自学了如何为 Android 开发。提前致谢。

我看到你没有正确关闭标签键盘。

<Keyboard xmlns:android="http://schemas.android.com/apk/res/android">
    android:keyWidth="10%p"
    android:verticalGap="0px"
    android:horizontalGap="0px"

应该写成:

<Keyboard xmlns:android="http://schemas.android.com/apk/res/android"
    android:keyWidth="10%p"
    android:verticalGap="0px"
    android:horizontalGap="0px">

根据 Xbalanqué 的回答,尝试在键盘标签中设置 keyHeight:

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