Tạo bàn phím mang phong cách của riêng bạn trong Android
Bài đăng này đã không được cập nhật trong 3 năm
Hôm bữa thấy người yêu mình xài điện thoại có cái bàn phím mà style nó hơi bị đẹp Mình cũng thấy hay hay , thế là lân la gạ hỏi hóa ra cô ấy xài Swift Key , thế là cũng cài vào , thế rồi thắc mắc là tại sao họ có thể làm được cái bàn phím đẹp như thế
Thế là sau vài chục phút mày mò , mình cũng làm ra được 1 cái bàn phím của riêng mình , tuy không cute phô mai que như Swift nhưng kệ , trước mắt cứ như thế đã Rồi từ từ cải tiến sau , cái gì mà chả có phiên bản 1.0
Okay ! Bắt đầu nào , trước tiên là Demo , tính mình là làm cái gì thì làm trước tiên là phải show kết quả đã rồi nói chuyện sau
Vào Settings -> Virtual Keyboard -> Enable cái custom keyboard của mình
Sau đó chỉ việc change bàn phím
Kết quả nè :
Hehehe , bắt đầu thôi , đầu tiên các bạn hãy tạo 1 dự án mới , nhớ là không cần tạo Launcher activity nhé , vì trong ví dụ này chúng ta chạy Service , ko chạy launcher activity (Service là gì thì cứ document của Android mà đọc cho nó chính phái)
Sau khi có dự án rồi , trong thư mục layout tạo ra 2 file XML lần lượt là
- key_preview.xml (file này sẽ là giao diện để cho các bạn preview character khi select phím)
<?xml version="1.0" encoding="utf-8"?>
<TextView
xmlns:android="http://schemas.android.com/apk/res/android"
android:gravity="center"
android:background="#5d5d5d"
android:textColor="@android:color/white"
android:textStyle="italic"
android:textSize="30sp"
android:layout_width="match_parent"
android:layout_height="match_parent">
</TextView>
- keyboard.xml (file này là file UI layout của bàn phím)
<?xml version="1.0" encoding="utf-8"?>
<android.inputmethodservice.KeyboardView
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/keyboard"
android:layout_alignParentBottom="true"
android:keyTextColor="@android:color/white"
android:keyBackground="@drawable/key_background"
android:keyPreviewLayout="@layout/key_preview"
android:background="@color/colorPrimaryDark"
android:layout_width="match_parent"
android:layout_height="wrap_content">
</android.inputmethodservice.KeyboardView>
Tiếp theo , click chuột phải vào thư mục res->Add resources directory -> xml
![](https://images.viblo.asia/5e927348-7b8e-466d-9819-7550d714c51f.png)
Trong thư mục mới tạo này (xml) , các bạn tạo tiếp 2 file
- method.xml (Đây là file cấu hình kiểu , ngôn ngữ của bàn phím)
<?xml version="1.0" encoding="utf-8"?>
<input-method xmlns:android="http://schemas.android.com/apk/res/android">
<subtype
android:label="English (US)"
android:imeSubtypeLocale="en_US"
android:imeSubtypeMode="keyboard"
/>
</input-method>
- qwerty.xml (Đây là file cấu hình các phím)
<?xml version="1.0" encoding="utf-8"?>
<Keyboard xmlns:android="http://schemas.android.com/apk/res/android"
android:keyWidth="10%p"
android:horizontalGap="0px"
android:verticalGap="0px"
android:keyHeight="60dp">
<Row>
<Key android:keyLabel="1"
android:keyEdgeFlags="left"
android:codes="49"/>
<Key android:keyLabel="2"
android:codes="50"/>
<Key android:keyLabel="3"
android:codes="51"/>
<Key android:keyLabel="4"
android:codes="52"/>
<Key android:keyLabel="5"
android:codes="53"/>
<Key android:keyLabel="6"
android:codes="54"/>
<Key android:keyLabel="7"
android:codes="55"/>
<Key android:keyLabel="8"
android:codes="56"/>
<Key android:keyLabel="9"
android:codes="57"/>
<Key android:keyLabel="0"
android:keyEdgeFlags="right"
android:codes="48"/>
</Row>
<Row>
<Key android:keyLabel="q" android:keyEdgeFlags="left" android:codes="113"/>
<Key android:keyLabel="w" android:codes="119"/>
<Key android:keyLabel="e" android:codes="101"/>
<Key android:keyLabel="r" android:codes="114"/>
<Key android:keyLabel="t" android:codes="116"/>
<Key android:keyLabel="y" android:codes="121"/>
<Key android:keyLabel="u" android:codes="117"/>
<Key android:keyLabel="i" android:codes="105"/>
<Key android:keyLabel="o" android:codes="111"/>
<Key android:keyLabel="p" android:keyEdgeFlags="right" android:codes="112"/>
</Row>
<Row>
<Key android:keyLabel="a" android:keyEdgeFlags="left" android:codes="97"/>
<Key android:keyLabel="s" android:codes="115"/>
<Key android:keyLabel="d" android:codes="100"/>
<Key android:keyLabel="f" android:codes="102"/>
<Key android:keyLabel="g" android:codes="103"/>
<Key android:keyLabel="h" android:codes="104"/>
<Key android:keyLabel="j" android:codes="106"/>
<Key android:keyLabel="k" android:codes="107"/>
<Key android:keyLabel="l" android:codes="108"/>
<Key android:keyLabel="\# \@" android:keyEdgeFlags="right" android:codes="35,64"/>
</Row>
<Row>
<Key android:keyLabel="CAPS" android:keyEdgeFlags="left" android:codes="-1"/>
<Key android:keyLabel="z" android:codes="122"/>
<Key android:keyLabel="x" android:codes="120"/>
<Key android:keyLabel="c" android:codes="99"/>
<Key android:keyLabel="v" android:codes="118"/>
<Key android:keyLabel="b" android:codes="98"/>
<Key android:keyLabel="n" android:codes="110"/>
<Key android:keyLabel="m" android:codes="109"/>
<Key android:keyLabel="." android:codes="46"/>
<Key android:keyLabel="\? ! :" android:keyEdgeFlags="right" android:codes="63,33,58"/>
</Row>
<Row android:rowEdgeFlags="bottom">
<Key android:keyLabel="," android:keyWidth="10%p" android:keyEdgeFlags="left" android:codes="44"/>
<Key android:keyLabel="/" android:keyWidth="10%p" android:codes="47"/>
<Key android:keyLabel="SPACE" android:keyWidth="40%p" android:isRepeatable="true" android:codes="32"/>
<Key android:keyLabel="DEL" android:keyWidth="20%p" android:isRepeatable="true" android:codes="-5"/>
<Key android:keyLabel="DONE" android:keyWidth="20%p" android:keyEdgeFlags="right" android:codes="-4"/>
</Row>
</Keyboard>
Trong này thì các bạn chỉ cần chú ý các tham số sau android:keyEdgeFlags="left" => Đây là vị trí của phím android:keyLabel="b" => Label hiển thị trên màn hình android:codes="98" => Mã code của ký tự (ASCII code)
Okay , bây giờ , chúng ta cần tạo 1 Service để xử lý đống trên , click phải vào package name và chọn NEw -> Servc
Code của Service
public class EDMTKeyboard extends InputMethodService implements KeyboardView.OnKeyboardActionListener {
private KeyboardView kv;
private Keyboard keyboard;
private boolean isCaps = false;
//Press Ctrl+O
@Override
public View onCreateInputView() {
kv = (KeyboardView)getLayoutInflater().inflate(R.layout.keyboard,null);
keyboard = new Keyboard(this,R.xml.qwerty);
kv.setKeyboard(keyboard);
kv.setOnKeyboardActionListener(this);
return kv;
}
@Override
public void onPress(int i) {
}
@Override
public void onRelease(int i) {
}
@Override
public void onKey(int i, int[] ints) {
InputConnection ic = getCurrentInputConnection();
playClick(i);
switch (i)
{
case Keyboard.KEYCODE_DELETE:
ic.deleteSurroundingText(1,0);
break;
case Keyboard.KEYCODE_SHIFT:
isCaps = !isCaps;
keyboard.setShifted(isCaps);
kv.invalidateAllKeys();
break;
case Keyboard.KEYCODE_DONE:
ic.sendKeyEvent(new KeyEvent(KeyEvent.ACTION_DOWN,KeyEvent.KEYCODE_ENTER));
break;
default:
char code = (char)i;
if(Character.isLetter(code) && isCaps)
code = Character.toUpperCase(code);
ic.commitText(String.valueOf(code),1);
}
}
private void playClick(int i) {
AudioManager am = (AudioManager)getSystemService(AUDIO_SERVICE);
switch(i)
{
case 32:
am.playSoundEffect(AudioManager.FX_KEYPRESS_SPACEBAR);
break;
case Keyboard.KEYCODE_DONE:
case 10:
am.playSoundEffect(AudioManager.FX_KEYPRESS_RETURN);
break;
case Keyboard.KEYCODE_DELETE:
am.playSoundEffect(AudioManager.FX_KEYPRESS_DELETE);
break;
default: am.playSoundEffect(AudioManager.FX_KEYPRESS_STANDARD);
}
}
@Override
public void onText(CharSequence charSequence) {
}
@Override
public void swipeLeft() {
}
@Override
public void swipeRight() {
}
@Override
public void swipeDown() {
}
@Override
public void swipeUp() {
}
}
@Override public View onCreateInputView() { kv = (KeyboardView)getLayoutInflater().inflate(R.layout.keyboard,null); keyboard = new Keyboard(this,R.xml.qwerty); kv.setKeyboard(keyboard); kv.setOnKeyboardActionListener(this); return kv; } Trong hàm này , chúng ta đã xử lý việc khởi tạo 1 virtual keyboard từ giao diện riêng của chúng ta , sau đó set các sự kiện cho nó
@Override
public void onKey(int i, int[] ints) {
InputConnection ic = getCurrentInputConnection();
playClick(i);
switch (i)
{
case Keyboard.KEYCODE_DELETE:
ic.deleteSurroundingText(1,0);
break;
case Keyboard.KEYCODE_SHIFT:
isCaps = !isCaps;
keyboard.setShifted(isCaps);
kv.invalidateAllKeys();
break;
case Keyboard.KEYCODE_DONE:
ic.sendKeyEvent(new KeyEvent(KeyEvent.ACTION_DOWN,KeyEvent.KEYCODE_ENTER));
break;
default:
char code = (char)i;
if(Character.isLetter(code) && isCaps)
code = Character.toUpperCase(code);
ic.commitText(String.valueOf(code),1);
}
}
Trong hàm này , chúng ta sẽ xử lý những nút đặc biệt như : Click vào nút DELETE thì xóa ký tự hiện tại , click vào nút SHIFT thì cho phép viết hoa , click vào nút Enter thì xuống dòng , còn lại các nút kia thì in character của nó ra
private void playClick(int i) {
AudioManager am = (AudioManager)getSystemService(AUDIO_SERVICE);
switch(i)
{
case 32:
am.playSoundEffect(AudioManager.FX_KEYPRESS_SPACEBAR);
break;
case Keyboard.KEYCODE_DONE:
case 10:
am.playSoundEffect(AudioManager.FX_KEYPRESS_RETURN);
break;
case Keyboard.KEYCODE_DELETE:
am.playSoundEffect(AudioManager.FX_KEYPRESS_DELETE);
break;
default: am.playSoundEffect(AudioManager.FX_KEYPRESS_STANDARD);
}
}
Hàm này sẽ play âm thanh khi chúng ta nhấn phím
Okay , và đừng quên khai báo Service trong Manifest nhé
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="edmt.dev.androidcustomkeyboard">
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<service
android:name=".EDMTKeyboard"
android:label="EDMTKeyboard"
android:permission="android.permission.BIND_INPUT_METHOD"
>
<meta-data android:name="android.view.im" android:resource="@xml/method"/>
<intent-filter>
<action android:name="android.view.InputMethod"/>
</intent-filter>
</service>
</application>
</manifest>
Đây là file colors.xml của mình , màu đúng y như demo nhé (vì mình set màu bàn phím theo colorPrimary và colorPrimaryDark)
<?xml version="1.0" encoding="utf-8"?>
<resources>
<color name="colorPrimary">#3F51B5</color>
<color name="colorPrimaryDark">#303F9F</color>
<color name="colorAccent">#FF4081</color>
<color name="keyboard_background_color">#34495e</color>
<color name="keyboard_divider">#2c3e50</color>
<color name="keyboard_pressed">#95a5a6</color>
</resources>
Và hãy thưởng thức nào
All rights reserved