Bagaimana Anda bisa membuat keyboard khusus di Android?

105

Saya ingin membuat keyboard khusus. Saya tidak tahu bagaimana melakukannya menggunakan XML dan Java. Gambar berikut adalah model keyboard yang ingin saya buat. Itu hanya membutuhkan angka.

masukkan deskripsi gambar di sini

XX_brother
sumber
6
[Buat Keyboard Kustom Anda Sendiri menggunakan Tata Letak XML untuk Perangkat Android] ( tutorials-android.blogspot.com/2011/06/… )
Jorgesys
1
Ada tutorial yang bagus di Tuts: link
Hamed Ghadirian
Google memiliki contoh proyek "SoftKeyboard", atau ada cukup banyak sumber daya yang ditautkan di sini: customkeyboarddetails.blogspot.com/2019/02/…
oliversisson

Jawaban:

83

Pertama-tama Anda akan membutuhkan keyboard.xmlfile yang akan ditempatkan di res/xmlfolder (jika folder tidak ada, buatlah).

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

** Perhatikan bahwa Anda harus membuat backspacedrawable dan menempatkannya di folder res / drawable-ldpi dengan ukuran yang sangat kecil (seperti 18x18 piksel)

Kemudian di file xml yang Anda inginkan untuk digunakan (di mana TextView Anda berada), Anda harus menambahkan kode berikut:

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

** Perhatikan bahwa file xml yang akan Anda tempatkan android.inputmethodservice.KeyboardView, RelativeLayoutharus bisa mengatur alignParentBottom="true"(Biasanya keyboard disajikan di bagian bawah layar)

Kemudian Anda perlu menambahkan kode berikut dalam onCreatefungsi Activityyang menangani TextViewAnda ingin memasang keyboard

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

** Perhatikan bahwa mKeyboarddan mKeyboardViewmerupakan variabel kelas privat yang harus Anda buat.

Kemudian Anda memerlukan fungsi berikut untuk membuka keyboard (Anda harus mengaitkannya dengan TextView melalui onClickproperti xml)

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

Dan akhirnya Anda membutuhkan OnKeyboardActionListeneryang akan menangani acara Anda

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

Semoga membantu !!!

Sebagian besar kode ditemukan di sini

Pontios
sumber
1
Bagaimana jika saya tidak ingin keyboard berada di bagian bawah layar? (mis. saya ingin pengguna dapat menyeretnya). Apakah itu sesuatu yang dapat saya kendalikan melalui aplikasi papan ketik saya atau apakah itu ditangani oleh sistem android?
pengguna3294126
lebar keyboard tidak memenuhi layar apa yang harus saya lakukan untuk membuatnya memenuhi semua layar
George Thomas
apa tata letak induk tempat KeyboardView berada? Juga sudahkah Anda memeriksa layout_width dari KeyboardView ??
Pontios
1
Perlu diketahui bahwa kelas KeyboardView dan Keyboard tidak digunakan lagi oleh Google sejak API level 29. Jadi, solusi ini tidak akan berfungsi lagi di masa mendatang jika Anda harus menargetkan level API yang lebih baru.
maex
keyboardView dihentikan oleh google. apa solusi baru?
tohidmahmoudvand
78

Keyboard sistem

Jawaban ini menjelaskan cara membuat keyboard sistem kustom yang dapat digunakan di aplikasi apa pun yang telah diinstal pengguna di ponsel mereka. Jika Anda ingin membuat keyboard yang hanya akan digunakan dalam aplikasi Anda sendiri, lihat jawaban saya yang lain .

Contoh di bawah ini akan terlihat seperti ini. Anda dapat memodifikasinya untuk tata letak keyboard apa pun.

masukkan deskripsi gambar di sini

Langkah-langkah berikut menunjukkan cara membuat keyboard sistem kustom yang berfungsi. Sebisa mungkin saya mencoba menghapus kode yang tidak perlu. Jika ada fitur lain yang Anda butuhkan, saya memberikan tautan ke bantuan lebih lanjut di bagian akhir.

1. Mulai proyek Android baru

Saya menamai proyek saya "Keyboard Khusus". Sebut saja sesuka Anda. Tidak ada hal lain yang istimewa di sini. Saya hanya akan meninggalkan MainActivitydan "Hello World!" tata letak apa adanya.

2. Tambahkan file tata letak

Tambahkan dua file berikut ke res/layoutfolder aplikasi Anda :

  • keyboard_view.xml
  • key_preview.xml

keyboard_view.xml

Tampilan ini seperti wadah yang akan menahan keyboard kita. Dalam contoh ini hanya ada satu keyboard, tetapi Anda dapat menambahkan keyboard lain dan menukarnya masuk dan keluar dari ini 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>

key_preview.xml

Pratinjau tombol adalah tata letak yang muncul saat Anda menekan tombol keyboard. Itu hanya menunjukkan tombol apa yang Anda tekan (jika jari-jari besar dan gemuk Anda menutupinya). Ini bukan popup pilihan ganda. Untuk itu Anda harus melihat tampilan Kandidat .

<?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. Tambahkan file xml pendukung

Buat xmlfolder di resfolder Anda . (Klik kanan resdan pilih New> Directory .)

Kemudian tambahkan dua file xml berikut ke dalamnya. (Klik kanan xmlfolder dan pilih New> XML resource file .)

  • number_pad.xml
  • method.xml

number_pad.xml

Di sinilah mulai menjadi lebih menarik. Ini Keyboardmendefinisikan tata letak kunci .

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

Berikut beberapa hal yang perlu diperhatikan:

  • keyWidth: Ini adalah lebar default setiap kunci. The 20%pberarti bahwa setiap tombol harus mengambil 20% dari lebar p Arent. Ini dapat diganti dengan kunci individu, seperti yang Anda lihat terjadi dengan tombol Delete dan Enter di baris ketiga.
  • keyHeight: Ini sulit dikodekan di sini, tetapi Anda dapat menggunakan sesuatu seperti @dimen/key_heightuntuk menyetelnya secara dinamis untuk ukuran layar yang berbeda.
  • Gap: Celah horizontal dan vertikal menunjukkan berapa banyak ruang yang tersisa di antara tombol. Bahkan jika Anda mengaturnya, 0pxmasih ada celah kecil.
  • codes: Ini bisa berupa Unicode atau nilai kode khusus yang menentukan apa yang terjadi atau apa yang dimasukkan saat tombol ditekan. Lihat keyOutputTextapakah Anda ingin memasukkan string Unicode yang lebih panjang.
  • keyLabel: Ini adalah teks yang ditampilkan di tombol.
  • keyEdgeFlags: Ini menunjukkan tepi mana kunci harus sejajar.
  • isRepeatable: Jika Anda menahan tombol itu akan terus mengulangi masukan.

method.xml

File ini memberi tahu sistem subtipe metode masukan yang tersedia. Saya hanya memasukkan versi minimal di sini.

<?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. Tambahkan kode Java untuk menangani input tombol

Buat file Java baru. Sebut saja MyInputMethodService. File ini menyatukan semuanya. Ini menangani masukan yang diterima dari keyboard dan mengirimkannya ke tampilan apa pun yang menerimanya (sebuah EditText, misalnya).

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

Catatan:

  • The OnKeyboardActionListenermendengarkan untuk input keyboard. Itu juga membutuhkan semua metode kosong dalam contoh ini.
  • Inilah InputConnectionyang digunakan untuk mengirim input ke tampilan lain seperti EditText.

5. Perbarui manifes

Saya meletakkan ini yang terakhir daripada yang pertama karena ini mengacu pada file yang sudah kami tambahkan di atas. Untuk mendaftarkan keyboard kustom Anda sebagai keyboard sistem, Anda perlu menambahkan servicebagian ke file AndroidManifest.xml Anda . Letakkan di applicationbagian setelah 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>

Itu dia! Anda seharusnya dapat menjalankan aplikasi Anda sekarang. Namun, Anda tidak akan melihat banyak sampai Anda mengaktifkan keyboard Anda di pengaturan.

6. Aktifkan keyboard di Pengaturan

Setiap pengguna yang ingin menggunakan keyboard Anda harus mengaktifkannya di pengaturan Android. Untuk petunjuk mendetail tentang cara melakukannya, lihat tautan berikut:

Berikut ringkasannya:

  • Buka Pengaturan Android> Bahasa dan masukan> Keyboard saat ini> Pilih keyboard.
  • Anda harus melihat Keyboard Kustom Anda di daftar. Aktifkan.
  • Kembali dan pilih Keyboard saat ini lagi. Anda harus melihat Keyboard Kustom Anda di daftar. Pilih itu.

Sekarang Anda harus dapat menggunakan keyboard Anda di mana pun Anda dapat mengetik di Android.

Pelajaran lanjutan

Keyboard di atas dapat digunakan, tetapi untuk membuat keyboard yang ingin digunakan orang lain, Anda mungkin harus menambahkan lebih banyak fungsionalitas. Pelajari tautan di bawah untuk mempelajari caranya.

Sedang terjadi

Tidak suka KeyboardViewtampilan dan perilaku standar ? Saya pasti tidak. Sepertinya belum diperbarui sejak Android 2.0. Bagaimana dengan semua keyboard khusus di Play Store? Mereka tidak terlihat seperti keyboard jelek di atas.

Kabar baiknya adalah Anda dapat sepenuhnya menyesuaikan tampilan dan perilaku papan ketik Anda sendiri. Anda perlu melakukan hal-hal berikut:

  1. Buat tampilan keyboard kustom Anda sendiri yang merupakan subclass ViewGroup. Anda dapat mengisinya dengan Buttons atau bahkan membuat tampilan kunci kustom Anda sendiri untuk subkelas tersebut View. Jika Anda menggunakan tampilan popup, catat ini .
  2. Tambahkan antarmuka pendengar acara khusus di keyboard Anda. Sebut metodenya untuk hal-hal seperti onKeyClicked(String text)atau onBackspace().
  3. Anda tidak perlu menambahkan keyboard_view.xml, key_preview.xmlatau number_pad.xmldijelaskan dalam arah atas, karena ini semua untuk standar KeyboardView. Anda akan menangani semua aspek UI ini dalam tampilan kustom Anda.
  4. Di MyInputMethodServicekelas Anda , terapkan pendengar keyboard khusus yang Anda tentukan di kelas keyboard Anda. Ini menggantikan KeyboardView.OnKeyboardActionListener, yang tidak lagi dibutuhkan.
  5. Dalam metode MyInputMethodServicekelas Anda onCreateInputView(), buat dan kembalikan instance dari keyboard kustom Anda. Jangan lupa untuk menyetel pendengar khusus keyboard ke this.
Suragch
sumber
35

Keyboard Dalam Aplikasi

Jawaban ini menjelaskan cara membuat keyboard kustom untuk digunakan secara eksklusif dalam aplikasi Anda. Jika Anda ingin membuat keyboard sistem yang dapat digunakan di aplikasi apa pun, lihat jawaban saya yang lain .

Contohnya akan terlihat seperti ini. Anda dapat memodifikasinya untuk tata letak keyboard apa pun.

masukkan deskripsi gambar di sini

1. Mulai proyek Android baru

Saya menamai proyek saya InAppKeyboard. Panggil punyamu sesuka kamu.

2. Tambahkan file tata letak

Tata letak keyboard

Tambahkan file tata letak ke res/layoutfolder. Aku menelepon milikku keyboard. Keyboard akan menjadi tampilan gabungan khusus yang akan kami perbesar dari file tata letak xml ini. Anda dapat menggunakan tata letak apa pun yang Anda suka untuk mengatur kunci, tetapi saya menggunakan file LinearLayout. Catat mergetagnya.

res / layout / 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>

Tata letak aktivitas

Untuk tujuan demonstrasi, aktivitas kami memiliki satu EditTextdan keyboard ada di bagian bawah. Saya menyebut tampilan keyboard kustom saya MyKeyboard. (Kami akan segera menambahkan kode ini, jadi abaikan kesalahannya untuk saat ini.) Manfaat meletakkan semua kode keyboard kami ke dalam satu tampilan adalah membuatnya mudah untuk digunakan kembali di aktivitas atau aplikasi lain.

res / layout / 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>

3. Tambahkan file Keyboard Java

Tambahkan file Java baru. Aku menelepon milikku MyKeyboard.

Hal terpenting untuk diperhatikan di sini adalah bahwa tidak ada tautan keras ke salah satu EditTextatau Activity. Ini membuatnya mudah untuk dicolokkan ke aplikasi atau aktivitas apa pun yang membutuhkannya. Tampilan papan ketik khusus ini juga menggunakan InputConnection, yang meniru cara papan ketik sistem berkomunikasi dengan EditText. Inilah cara kami menghindari tautan keras.

MyKeyboard adalah tampilan gabungan yang memperbesar tata letak tampilan yang kami tentukan di atas.

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. Arahkan keyboard ke EditText

Untuk keyboard sistem, Android menggunakan InputMethodManager untuk mengarahkan keyboard ke fokus EditText. Dalam contoh ini, aktivitas akan berlangsung dengan menyediakan link dari EditTextke keyboard kustom kita ke.

Karena kami tidak menggunakan keyboard sistem, kami perlu menonaktifkannya agar tidak muncul saat kami menyentuh EditText. Kedua, kita perlu mendapatkan InputConnectiondari EditTextdan memberikannya ke keyboard kita.

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

Jika Aktivitas Anda memiliki beberapa EditText, maka Anda perlu menulis kode untuk meneruskan EditText yang benar InputConnectionke keyboard. (Anda dapat melakukan ini dengan menambahkan OnFocusChangeListenerdan OnClickListenerke EditTexts. Lihat artikel ini untuk pembahasannya.) Anda mungkin juga ingin menyembunyikan atau menampilkan keyboard Anda pada waktu yang tepat.

Jadi

Itu dia. Anda seharusnya dapat menjalankan aplikasi contoh sekarang dan memasukkan atau menghapus teks sesuai keinginan. Langkah Anda selanjutnya adalah memodifikasi semuanya agar sesuai dengan kebutuhan Anda sendiri. Misalnya, di beberapa keyboard saya, saya telah menggunakan TextView daripada Buttons karena lebih mudah untuk menyesuaikannya.

Catatan

  • Di file layout xml, Anda juga bisa menggunakan TextViewa Buttonjika Anda ingin membuat kunci terlihat lebih baik. Lalu buat saja latar belakang menjadi drawable yang mengubah status tampilan saat ditekan.
  • Keyboard kustom lanjutan: Untuk fleksibilitas lebih dalam tampilan keyboard dan peralihan keyboard, saya sekarang membuat tampilan tombol kustom yang subkelas Viewdan keyboard kustom yang subkelas ViewGroup. Keyboard menjabarkan semua tombol secara terprogram. Tombol tersebut menggunakan antarmuka untuk berkomunikasi dengan keyboard (mirip dengan cara fragmen berkomunikasi dengan suatu aktivitas). Ini tidak diperlukan jika Anda hanya memerlukan satu tata letak keyboard karena tata letak xml berfungsi dengan baik untuk itu. Tetapi jika Anda ingin melihat contoh dari apa yang telah saya kerjakan, lihat semua kelas Key*dan di sini . Perhatikan bahwa saya juga menggunakan tampilan kontainer di sana yang fungsinya untuk menukar keyboard masuk dan keluar.Keyboard*
Suragch
sumber
jawaban Anda bagus, tetapi bagaimana kami dapat mengatur peralihan antara keyboard asli dan keyboard baru ini.
Kishan Donga
@KishanDonga, Pada keyboard Anda, Anda dapat menambahkan kunci untuk berpindah keyboard. Ketika pengguna menekannya, panggil InputMethodManager#showInputMethodPicker(). Jika keyboard asli tidak memiliki kunci seperti itu, satu-satunya cara pengguna dapat beralih ke keyboard Anda adalah dengan melakukannya secara manual dalam pengaturan sistem. Apple lebih unggul dari Android dalam hal ini, karena Apple mengharuskan semua keyboard memiliki tombol pengalih keyboard.
Suragch
@KishanDonga, saya baru menyadari bahwa jawaban ini tentang keyboard dalam aplikasi, bukan keyboard sistem. Jika Anda ingin beralih antara dua keyboard kustom, Anda dapat menukarnya secara terprogram masuk dan keluar dari tampilan penampung. Cukup tambahkan tombol keyboard swap di kedua keyboard. Lihat catatan dan tautan "papan ketik khusus lanjutan" saya di jawaban di atas.
Suragch
Jika Anda ingin beralih antara keyboard dan keyboard sistem, maka sembunyikan keyboard sistem dan tampilkan keyboard Anda pada waktu yang tepat (dan sebaliknya).
Suragch
1
@MarekTakac, Anda perlu menonaktifkan keyboard sistem dan menambahkan keyboard kustom Anda di setiap aktivitas. Jika suatu aktivitas memiliki beberapa EditTextdetik maka Anda perlu menambahkannya onFocusChangedListenersehingga ketika aktivitas tersebut menerima fokus, Anda dapat menetapkannya InputConnectiondari saat ini EditTextke keyboard kustom Anda.
Suragch
31

Penggunaan KeyboardView:

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

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

sekarang Anda memiliki kbdyang merupakan tampilan normal.

Hal yang menyenangkan tentang ini adalah R.xml.custommengacu pada /res/xml/custom.xml, yang mendefinisikan tata letak keyboard dalam xml. Untuk informasi lebih lanjut tentang file ini, lihat di sini: Keyboard , Keyboard.Row , Keyboard.Key .

batu besar
sumber
2
Saya menggunakan kelas KeyboardView, tetapi mulai API 29, sekarang sudah tidak digunakan lagi.
Abhijit
14

Berikut adalah contoh proyek untuk soft keyboard.

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

Anda harus berada di baris yang sama dengan tata letak yang berbeda.

Sunting: Jika Anda hanya membutuhkan keyboard di aplikasi Anda, itu sangat sederhana! Buat tata letak linier dengan orientasi vertikal, dan buat 3 tata letak linier di dalamnya dengan orientasi horizontal. Kemudian tempatkan tombol dari setiap baris di setiap tata letak linier horizontal tersebut, dan tetapkan properti bobot ke tombol. Gunakan android: layout_weight = 1 untuk semuanya, sehingga jarak keduanya sama.

Ini akan menyelesaikannya. Jika Anda tidak mendapatkan apa yang diharapkan, silakan posting kodenya di sini, dan kami di sini untuk membantu Anda!

nithinreddy
sumber
Pengeditan sebenarnya buruk karena itu berarti keyboard selalu ditampilkan dan tidak akan berperilaku seperti keyboard Android bawaan.
m0skit0
4

Saya menemukan posting ini baru-baru ini ketika saya mencoba memutuskan metode apa yang akan digunakan untuk membuat keyboard khusus saya sendiri. Saya menemukan API sistem Android sangat terbatas, jadi saya memutuskan untuk membuat keyboard dalam aplikasi saya sendiri. Menggunakan jawaban Suragch sebagai dasar penelitian saya, saya melanjutkan merancang komponen keyboard saya sendiri . Itu diposting di GitHub dengan lisensi MIT. Mudah-mudahan ini akan menghemat banyak waktu dan sakit kepala orang lain.

Arsitekturnya cukup fleksibel. Ada satu tampilan utama (CustomKeyboardView) yang dapat Anda masukkan dengan tata letak keyboard dan pengontrol apa pun yang Anda inginkan.

Anda hanya perlu mendeklarasikan CustomKeyboardView dalam aktivitas Anda xml (Anda juga dapat melakukannya secara terprogram):

    <com.donbrody.customkeyboard.components.keyboard.CustomKeyboardView
    android:id="@+id/customKeyboardView"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_alignParentBottom="true" />

Kemudian daftarkan EditText Anda dengannya dan beri tahu jenis keyboard apa yang harus mereka gunakan:

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 menangani sisanya!

Saya mendapatkan bola menggelinding dengan keyboard Number, NumberDecimal, dan QWERTY. Jangan ragu untuk mengunduhnya dan membuat tata letak dan pengontrol Anda sendiri. Ini terlihat seperti ini:

Lanskap gif keyboard kustom android

masukkan deskripsi gambar di sini

Meskipun ini bukan arsitektur yang Anda pilih, semoga akan membantu jika melihat kode sumber untuk keyboard dalam aplikasi yang berfungsi.

Sekali lagi, inilah tautan ke proyek: Keyboard Dalam Aplikasi Khusus

Don Brody
sumber
2

Sejauh ini, Suragch memberikan jawaban terbaik, tetapi dia melewatkan hal-hal kecil tertentu yang penting untuk membuat aplikasi itu terkompilasi.

Saya berharap dapat membuat jawaban yang lebih baik dari Suragch dengan memperbaiki jawabannya. Saya akan menambahkan semua elemen yang hilang yang tidak dia masukkan.

Saya menyusun apk saya menggunakan aplikasi android, APK Builder 1.1.0. Jadi mari kita mulai.

Untuk membangun aplikasi Android, kita memerlukan beberapa file dan folder yang diatur dalam format tertentu dan dikapitalisasi sesuai.

res layout -> file xml yang menggambarkan bagaimana tampilan aplikasi di ponsel. Mirip dengan bagaimana html membentuk tampilan halaman web di browser. Mengizinkan aplikasi Anda agar sesuai di layar.

nilai -> data konstan seperti colors.xml, strings.xml, styles.xml. File-file ini harus dieja dengan benar.

drawable -> foto {jpeg, png, ...}; Beri nama apa saja.

mipmap -> lebih banyak foto. digunakan untuk ikon aplikasi?

xml -> lebih banyak file xml.

src -> bertindak seperti JavaScript di html. file tata letak akan memulai tampilan awal dan file java Anda akan secara dinamis mengontrol elemen tag dan memicu peristiwa. Acara juga dapat diaktifkan langsung di layout.xml seperti di html.

AndroidManifest.xml -> File ini mendaftarkan tentang aplikasi Anda. Nama aplikasi, Jenis program, izin yang diperlukan, dll. Hal ini tampaknya membuat Android lebih aman. Program benar-benar tidak dapat melakukan apa yang tidak mereka minta dalam Manifes.

Sekarang ada 4 jenis program Android, aktivitas, layanan, penyedia konten, dan penerima siaran. Keyboard kami akan menjadi layanan, yang memungkinkannya berjalan di latar belakang. Ini tidak akan muncul di daftar aplikasi yang akan diluncurkan; tapi itu bisa dicopot.

Untuk mengompilasi aplikasi Anda, melibatkan gradle, dan penandatanganan apk. Anda dapat meneliti itu atau menggunakan Pembuat APK untuk android. Ini sangat mudah.

Sekarang setelah kita memahami pengembangan Android, mari kita buat file dan foldernya.

  1. Buat file dan folder seperti yang saya bahas di atas. Direktori saya akan terlihat sebagai berikut:

    • Papan Angka
      • AndroidManifest.xml
      • src
        • Saragch
          • num_pad
            • MyInputMethodService.java
      • res
        • drawable
          • Suragch_NumPad_icon.png
        • tata letak
          • key_preview.xml
          • keyboard_view.xml
        • xml
          • method.xml
          • number_pad.xml
        • nilai-nilai
          • colors.xml
          • strings.xml
          • styles.xml

Ingat jika Anda menggunakan ide seperti Android Studio, mungkin memiliki file proyek.

  1. Tulis file.

J: Papan Angka / res / layout / 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>

B: Papan Angka / res / layout / keyboard_view.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: Papan Angka / res / xml / metode.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: Numpad / res / xml / number_pad.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>

Tentu saja ini bisa dengan mudah diedit sesuai keinginan Anda. Anda bahkan dapat menggunakan gambar sebagai pengganti kata-kata untuk label.

Suragch tidak mendemonstrasikan file dalam folder values ​​dan menganggap kami memiliki akses ke Android Studio; yang secara otomatis membuatnya. Untung saya memiliki Pembuat APK.

E: Papan Angka / res / nilai / warna.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: Papan Angka / res / nilai / strings.xml

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

G: Papan Angka / res / nilai / gaya.xml

<resources>

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

</resources>

H: Numpad / AndroidManifest.xml

Ini adalah file yang benar-benar dapat diperdebatkan. Di sini saya merasa saya tidak akan pernah menyusun program saya. menangis. menangis. Jika Anda memeriksa jawaban Suracgh, Anda melihat dia membiarkan set field pertama kosong, dan menambahkan tag aktivitas dalam file ini. Seperti yang saya katakan ada empat jenis program Android. Aktivitas adalah aplikasi biasa dengan ikon peluncur. Numpad ini bukan aktivitas! Selanjutnya dia tidak melaksanakan aktivitas apapun.

Teman saya tidak menyertakan tag aktivitas. Program Anda akan dikompilasi, dan ketika Anda mencoba meluncurkannya akan macet! Adapun xmlns: android dan using-sdk; Saya tidak dapat membantu Anda di sana. Coba saja pengaturan saya jika berfungsi.

Seperti yang Anda lihat, ada tag layanan, yang mendaftarkannya sebagai layanan. Juga service.android:name haruslah nama layanan perluasan kelas publik di file java kita. Ini HARUS menggunakan huruf besar sebagaimana mestinya. Juga paket adalah nama dari paket yang kami deklarasikan dalam file 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: NumPad / src / Saragch / num_pad / MyInputMethodService.java

Catatan: Menurut saya java adalah alternatif dari src.

Ini adalah file masalah lain tetapi tidak sesulit file manifes. Seperti yang saya tahu Java cukup baik untuk mengetahui apa itu apa, apa yang tidak. Saya hampir tidak tahu xml dan bagaimana hubungannya dengan pengembangan Android!

Masalahnya di sini adalah dia tidak mengimpor apapun! Maksudku, dia memberi kami file "lengkap" yang menggunakan nama yang tidak bisa diselesaikan! InputMethodService, Keyboard, dll. Itu adalah latihan yang buruk Pak Suragch. Terima kasih telah membantu saya tetapi bagaimana Anda mengharapkan kode untuk dikompilasi jika nama tidak dapat diselesaikan?

Berikut ini adalah versi yang diedit dengan benar. Saya kebetulan menerkam beberapa petunjuk untuk mengantarkan saya ke tempat yang tepat untuk mempelajari apa yang sebenarnya harus diimpor.

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. Kompilasi dan tanda tangani proyek Anda.

    Di sinilah saya tidak mengerti sebagai pemula oleh pengembang Android. Saya ingin mempelajarinya secara manual, karena saya yakin programmer sejati dapat mengkompilasi secara manual.

Menurut saya gradle adalah salah satu alat untuk menyusun dan mengemas ke apk. apk tampaknya seperti file jar atau rar untuk file zip. Kemudian ada dua jenis penandatanganan. kunci debug yang tidak diizinkan di play store dan kunci pribadi.

Baiklah, mari kita bantu Tuan Saragch. Dan terima kasih telah menonton video saya. Suka, berlangganan.

marc_s
sumber