Tôi muốn tạo một bàn phím tùy chỉnh. Tôi không biết cách sử dụng XML và Java. Hình ảnh sau đây là mô hình bàn phím mà tôi muốn làm. Nó chỉ cần những con số.
Tôi muốn tạo một bàn phím tùy chỉnh. Tôi không biết cách sử dụng XML và Java. Hình ảnh sau đây là mô hình bàn phím mà tôi muốn làm. Nó chỉ cần những con số.
Câu trả lời:
Trước hết, bạn sẽ cần một keyboard.xml
tệp sẽ được đặt trong res/xml
thư mục (nếu thư mục không tồn tại, hãy tạo nó).
<?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>
** Lưu ý rằng bạn sẽ phải tạo backspace
vẽ và đặt nó trong thư mục res / drawable-ldpi với kích thước rất nhỏ (như 18x18 pixel)
Sau đó, trong tệp xml mà bạn muốn nó được sử dụng (nơi chứa TextView của bạn), bạn nên thêm mã sau:
<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>
** Lưu ý rằng tệp xml mà bạn sẽ đặt android.inputmethodservice.KeyboardView
vào, phải có RelativeLayout
để có thể thiết lậpalignParentBottom="true"
(Thông thường các bàn phím được trình bày ở cuối màn hình)
Sau đó, bạn cần thêm mã sau vào onCreate
chức năng của bộ Activity
xử lý TextView
mà bạn muốn gắn bàn phím vào
// 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);
** Lưu ý rằng mKeyboard
và mKeyboardView
là các biến lớp riêng mà bạn phải tạo.
Sau đó, bạn cần hàm sau để mở bàn phím (bạn phải liên kết nó với TextView thông qua thuộc tính onClick
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);
}
Và cuối cùng bạn cần OnKeyboardActionListener
cái sẽ xử lý các sự kiện của bạn
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() {
}
};
Hy vọng rằng sẽ giúp !!!
Hầu hết các mã được tìm thấy ở đây
Câu trả lời này cho biết cách tạo bàn phím hệ thống tùy chỉnh có thể được sử dụng trong bất kỳ ứng dụng nào mà người dùng đã cài đặt trên điện thoại của họ. Nếu bạn muốn tạo một bàn phím chỉ được sử dụng trong ứng dụng của riêng bạn, hãy xem câu trả lời khác của tôi .
Ví dụ dưới đây sẽ như thế này. Bạn có thể sửa đổi nó cho bất kỳ bố cục bàn phím nào.
Các bước sau đây cho biết cách tạo bàn phím hệ thống tùy chỉnh đang hoạt động. Tôi đã cố gắng xóa mọi mã không cần thiết càng nhiều càng tốt. Nếu có các tính năng khác mà bạn cần, tôi đã cung cấp các liên kết để được trợ giúp thêm ở cuối.
Tôi đặt tên cho dự án của mình là "Bàn phím tùy chỉnh". Gọi nó là bất cứ điều gì bạn muốn. Không có gì khác đặc biệt ở đây. Tôi sẽ chỉ rời khỏi MainActivity
và "Hello World!" bố cục như nó vốn có.
Thêm hai tệp sau vào res/layout
thư mục ứng dụng của bạn :
keyboard_view.xml
Chế độ xem này giống như một thùng chứa sẽ chứa bàn phím của chúng ta. Trong ví dụ này chỉ có một bàn phím, nhưng bạn có thể thêm các bàn phím khác và hoán đổi chúng vào và ra khỏi bàn phím này 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
Bản xem trước phím là một bố cục bật lên khi bạn nhấn một phím bàn phím. Nó chỉ hiển thị phím nào bạn đang nhấn (trong trường hợp ngón tay to và mập của bạn đang che nó). Đây không phải là một cửa sổ bật lên nhiều lựa chọn. Đối với điều đó, bạn nên xem chế độ xem Ứng viên .
<?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>
Tạo một xml
thư mục trong res
thư mục của bạn . (Nhấp chuột phải res
và chọn Mới> Thư mục .)
Sau đó, thêm hai tệp xml sau vào nó. (Nhấp chuột phải vào xml
thư mục và chọn Mới> Tệp tài nguyên XML .)
number_pad.xml
Đây là nơi nó bắt đầu trở nên thú vị hơn. Điều này Keyboard
xác định cách bố trí của các phím .
<?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>
Dưới đây là một số điều cần lưu ý:
keyWidth
: Đây là chiều rộng mặc định của mỗi khóa. Có 20%p
nghĩa là mỗi khóa phải chiếm 20% chiều rộng của p arent. Tuy nhiên, nó có thể bị ghi đè bởi các phím riêng lẻ, như bạn có thể thấy đã xảy ra với các phím Delete và Enter ở hàng thứ ba.keyHeight
: Nó được mã hóa cứng ở đây, nhưng bạn có thể sử dụng một cái gì đó như @dimen/key_height
để đặt nó động cho các kích thước màn hình khác nhau.Gap
: Khoảng cách ngang và dọc cho biết khoảng trống còn lại giữa các phím. Ngay cả khi bạn đặt nó 0px
vẫn còn một khoảng cách nhỏ.codes
: Đây có thể là giá trị mã Unicode hoặc mã tùy chỉnh xác định điều gì sẽ xảy ra hoặc những gì được nhập khi phím được nhấn. Xem keyOutputText
bạn có muốn nhập một chuỗi Unicode dài hơn không.keyLabel
: Đây là văn bản được hiển thị trên phím.keyEdgeFlags
: Điều này cho biết phím sẽ được căn chỉnh theo cạnh nào.isRepeatable
: Nếu bạn giữ phím, nó sẽ tiếp tục lặp lại quá trình nhập.method.xml
Tệp này cho hệ thống biết các kiểu con của phương thức nhập khả dụng. Tôi chỉ bao gồm một phiên bản tối thiểu ở đây.
<?xml version="1.0" encoding="utf-8"?>
<input-method
xmlns:android="http://schemas.android.com/apk/res/android">
<subtype
android:imeSubtypeMode="keyboard"/>
</input-method>
Tạo một tệp Java mới. Hãy gọi nó MyInputMethodService
. Tệp này liên kết mọi thứ với nhau. Nó xử lý đầu vào nhận được từ bàn phím và gửi nó đến bất kỳ chế độ xem nào đang nhận nó ( EditText
ví dụ).
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() { }
}
Ghi chú:
OnKeyboardActionListener
lắng nghe cho đầu vào bàn phím. Nó cũng yêu cầu tất cả các phương thức trống trong ví dụ này.InputConnection
những gì được sử dụng để gửi đầu vào đến một dạng xem khác như một EditText
.Tôi đặt điều này cuối cùng thay vì đầu tiên vì nó đề cập đến các tệp chúng tôi đã thêm ở trên. Để đăng ký bàn phím tùy chỉnh của bạn làm bàn phím hệ thống, bạn cần thêm một service
phần vào tệp AndroidManifest.xml của mình . Đặt nó trong application
phần sau 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>
Đó là nó! Bạn sẽ có thể chạy ứng dụng của mình ngay bây giờ. Tuy nhiên, bạn sẽ không thấy nhiều cho đến khi bật bàn phím của mình trong cài đặt.
Mọi người dùng muốn sử dụng bàn phím của bạn sẽ phải bật nó trong cài đặt Android. Để biết hướng dẫn chi tiết về cách làm điều đó, hãy xem liên kết sau:
Đây là một bản tóm tắt:
Giờ đây, bạn sẽ có thể sử dụng bàn phím của mình ở bất kỳ đâu mà bạn có thể nhập trong Android.
Bàn phím ở trên có thể sử dụng được, nhưng để tạo một bàn phím mà người khác muốn sử dụng, bạn có thể sẽ phải thêm nhiều chức năng hơn. Nghiên cứu các liên kết bên dưới để tìm hiểu cách thực hiện.
Không thích cách tiêu chuẩn KeyboardView
trông và cư xử? Tôi chắc chắn không. Có vẻ như nó đã không được cập nhật kể từ Android 2.0. Làm thế nào về tất cả các bàn phím tùy chỉnh đó trong Cửa hàng Play? Chúng trông không giống với bàn phím xấu xí ở trên.
Tin tốt là bạn hoàn toàn có thể tùy chỉnh giao diện và hành vi của bàn phím của riêng mình. Bạn sẽ cần thực hiện những việc sau:
ViewGroup
. Bạn có thể điền vào nó bằng Button
s hoặc thậm chí tạo các khung nhìn khóa tùy chỉnh của riêng bạn cho lớp con đó View
. Nếu bạn sử dụng dạng xem cửa sổ bật lên, thì hãy lưu ý điều này .onKeyClicked(String text)
hoặc onBackspace()
.keyboard_view.xml
, key_preview.xml
hoặc number_pad.xml
được mô tả trong các hướng dẫn ở trên vì đây là tất cả đối với tiêu chuẩn KeyboardView
. Bạn sẽ xử lý tất cả các khía cạnh giao diện người dùng này trong chế độ xem tùy chỉnh của mình.MyInputMethodService
lớp của bạn , hãy triển khai trình nghe bàn phím tùy chỉnh mà bạn đã xác định trong lớp bàn phím của mình. Điều này thay thế cho KeyboardView.OnKeyboardActionListener
, không còn cần thiết.MyInputMethodService
của lớp onCreateInputView()
, hãy tạo và trả về một phiên bản của bàn phím tùy chỉnh của bạn. Đừng quên đặt trình nghe tùy chỉnh của bàn phím thành this
.Câu trả lời này cho biết cách tạo bàn phím tùy chỉnh để sử dụng riêng trong ứng dụng của bạn. Nếu bạn muốn tạo một bàn phím hệ thống có thể được sử dụng trong bất kỳ ứng dụng nào, hãy xem câu trả lời khác của tôi .
Ví dụ sẽ như thế này. Bạn có thể sửa đổi nó cho bất kỳ bố cục bàn phím nào.
Tôi đặt tên cho dự án của mình InAppKeyboard
. Gọi của bạn bất cứ điều gì bạn muốn.
Bố cục bàn phím
Thêm tệp bố cục vào res/layout
thư mục. Tôi đã gọi cho tôi keyboard
. Bàn phím sẽ là một chế độ xem ghép tùy chỉnh mà chúng tôi sẽ tăng từ tệp bố cục xml này. Bạn có thể sử dụng bất kỳ bố cục nào bạn thích để sắp xếp các phím, nhưng tôi đang sử dụng a LinearLayout
. Lưu ý các merge
thẻ.
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>
Bố cục hoạt động
Với mục đích trình diễn, hoạt động của chúng tôi có một đĩa đơn EditText
và bàn phím ở dưới cùng. Tôi đã gọi chế độ xem bàn phím tùy chỉnh của mình MyKeyboard
. (Chúng tôi sẽ sớm thêm mã này vì vậy hãy bỏ qua lỗi ngay bây giờ.) Lợi ích của việc đặt tất cả mã bàn phím của chúng tôi vào một chế độ xem duy nhất là nó giúp bạn dễ dàng sử dụng lại trong một hoạt động hoặc ứng dụng khác.
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>
Thêm một tệp Java mới. Tôi đã gọi cho tôi MyKeyboard
.
Điều quan trọng nhất cần lưu ý ở đây là không có liên kết cứng đến bất kỳ EditText
hoặc Activity
. Điều này giúp bạn dễ dàng cắm nó vào bất kỳ ứng dụng hoặc hoạt động nào cần nó. Chế độ xem bàn phím tùy chỉnh này cũng sử dụng một InputConnection
, bắt chước cách bàn phím hệ thống giao tiếp với một EditText
. Đây là cách chúng tôi tránh các liên kết cứng.
MyKeyboard
là một dạng xem kết hợp làm phồng bố cục dạng xem mà chúng ta đã xác định ở trên.
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;
}
}
Đối với bàn phím hệ thống, Android sử dụng InputMethodManager để trỏ bàn phím vào tiêu điểm EditText
. Trong ví dụ này, hoạt động sẽ diễn ra bằng cách cung cấp liên kết từ EditText
bàn phím đến bàn phím tùy chỉnh của chúng tôi.
Vì chúng tôi không sử dụng bàn phím hệ thống, chúng tôi cần phải tắt nó để ngăn nó bật lên khi chúng tôi chạm vào EditText
. Thứ hai, chúng ta cần lấy InputConnection
từ EditText
và đưa nó vào bàn phím của mình.
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);
}
}
Nếu Hoạt động của bạn có nhiều EditText, thì bạn sẽ cần viết mã để chuyển EditText phù hợp InputConnection
vào bàn phím. (Bạn có thể làm điều này bằng cách thêm một OnFocusChangeListener
và OnClickListener
vào EditTexts. Xem bài viết này để thảo luận về điều đó.) Bạn cũng có thể muốn ẩn hoặc hiển thị bàn phím của mình vào những thời điểm thích hợp.
Đó là nó. Bạn sẽ có thể chạy ứng dụng mẫu ngay bây giờ và nhập hoặc xóa văn bản như mong muốn. Bước tiếp theo của bạn là sửa đổi mọi thứ để phù hợp với nhu cầu của riêng bạn. Ví dụ: trong một số bàn phím của tôi, tôi đã sử dụng TextViews thay vì Buttons vì tùy chỉnh chúng dễ dàng hơn.
TextView
chứ không phải một Button
nếu bạn muốn làm cho các phím trông đẹp hơn. Sau đó, chỉ cần làm cho nền có thể vẽ được và thay đổi trạng thái xuất hiện khi được nhấn.View
và bàn phím tùy chỉnh cho lớp con ViewGroup
. Bàn phím hiển thị tất cả các phím theo lập trình. Các phím sử dụng một giao diện để giao tiếp với bàn phím (tương tự như cách các mảnh giao tiếp với một hoạt động). Điều này là không cần thiết nếu bạn chỉ cần một bố cục bàn phím duy nhất vì bố cục xml hoạt động tốt cho điều đó. Nhưng nếu bạn muốn xem một ví dụ về những gì tôi đã và đang làm, hãy xem tất cả các Key*
và Keyboard*
các lớp học ở đây . Lưu ý rằng tôi cũng sử dụng chế độ xem vùng chứa ở đó có chức năng hoán đổi bàn phím vào và ra.InputMethodManager#showInputMethodPicker()
. Tuy nhiên, nếu bàn phím gốc không có phím như vậy, cách duy nhất người dùng có thể chuyển sang bàn phím của bạn là thực hiện thủ công trong cài đặt hệ thống. Apple vượt trội hơn Android trong lĩnh vực này, vì Apple yêu cầu tất cả các bàn phím phải có phím chuyển đổi bàn phím.
EditText
s thì bạn sẽ cần thêm một onFocusChangedListener
vào chúng để khi chúng nhận được tiêu điểm, bạn có thể gán InputConnection
từ hiện tại EditText
cho bàn phím tùy chỉnh của mình.
Sử dụng KeyboardView
:
KeyboardView kbd = new KeyboardView(context);
kbd.setKeyboard(new Keyboard(this, R.xml.custom));
kbd.setOnKeyboardActionListener(new OnKeyboardActionListener() {
....
}
bây giờ bạn có kbd
một cái nhìn bình thường.
Điều thú vị về điều này là R.xml.custom
đề cập đến /res/xml/custom.xml
, định nghĩa bố cục bàn phím trong xml. Để biết thêm thông tin về tệp này, hãy xem tại đây: Bàn phím , Bàn phím.Row , Bàn phím.Key .
Đây là một dự án mẫu cho một bàn phím mềm.
https://developer.android.com/guide/topics/text/creating-input-method.html
Của bạn phải ở cùng một dòng với một bố cục khác.
Chỉnh sửa: Nếu bạn chỉ cần bàn phím trong ứng dụng của mình, nó rất đơn giản! Tạo một bố cục tuyến tính với hướng dọc và tạo 3 bố cục tuyến tính bên trong nó với hướng ngang. Sau đó, đặt các nút của mỗi hàng trong mỗi bố cục tuyến tính nằm ngang đó và gán thuộc tính trọng số cho các nút. Sử dụng android: layout_weight = 1 cho tất cả chúng để chúng có khoảng cách đều nhau.
Điều này sẽ giải quyết. Nếu bạn không nhận được những gì mong đợi, vui lòng đăng mã ở đây và chúng tôi sẵn sàng trợ giúp bạn!
Một trong những ví dụ tốt nhất được ghi lại đầy đủ mà tôi tìm thấy.
http://www.fampennings.nl/maarten/android/09keyboard/index.htm
KeyboardView
tệp XML liên quan và mã nguồn được cung cấp.
Tôi đã xem qua bài đăng này gần đây khi tôi đang cố gắng quyết định phương pháp sử dụng để tạo bàn phím tùy chỉnh của riêng mình. Tôi nhận thấy API hệ thống Android rất hạn chế, vì vậy tôi quyết định tạo bàn phím trong ứng dụng của riêng mình. Sử dụng câu trả lời của Suragch làm cơ sở cho nghiên cứu của mình, tôi tiếp tục thiết kế thành phần bàn phím của riêng mình . Nó được đăng trên GitHub với giấy phép MIT. Hy vọng rằng điều này sẽ tiết kiệm cho người khác rất nhiều thời gian và đau đầu.
Kiến trúc khá linh hoạt. Có một chế độ xem chính (CustomKeyboardView) mà bạn có thể đưa vào với bất kỳ bố cục bàn phím và bộ điều khiển nào bạn muốn.
Bạn chỉ cần khai báo CustomKeyboardView trong xml hoạt động của bạn (bạn cũng có thể làm điều đó theo chương trình):
<com.donbrody.customkeyboard.components.keyboard.CustomKeyboardView
android:id="@+id/customKeyboardView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true" />
Sau đó đăng ký EditText của bạn với nó và cho nó biết loại bàn phím họ nên sử dụng:
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 xử lý phần còn lại!
Tôi đã có quả bóng lăn với bàn phím Number, NumberDecimal và QWERTY. Vui lòng tải xuống và tạo bố cục và bộ điều khiển của riêng bạn. Nó trông như thế này:
Ngay cả khi đây không phải là kiến trúc bạn quyết định sử dụng, hy vọng sẽ hữu ích khi xem mã nguồn cho bàn phím trong ứng dụng đang hoạt động.
Một lần nữa, đây là liên kết đến dự án: Bàn phím trong ứng dụng tùy chỉnh
Vâng, Suragch đã đưa ra câu trả lời tốt nhất cho đến nay nhưng anh ấy đã bỏ qua một số thứ nhỏ quan trọng để biên dịch ứng dụng.
Tôi hy vọng sẽ trả lời tốt hơn Suragch bằng cách cải thiện câu trả lời của anh ấy. Tôi sẽ bổ sung tất cả các yếu tố còn thiếu mà anh ấy đã không đặt.
Tôi đã biên dịch gói ứng dụng của mình bằng ứng dụng Android, Trình tạo APK 1.1.0. Vì vậy, hãy bắt đầu.
Để xây dựng một ứng dụng Android, chúng ta cần một vài tệp và thư mục được sắp xếp theo một định dạng nhất định và viết hoa tương ứng.
res layout -> các tệp xml mô tả cách ứng dụng sẽ trông như thế nào trên điện thoại. Tương tự như cách html định hình giao diện trang web trên trình duyệt. Cho phép ứng dụng của bạn phù hợp trên màn hình.
giá trị -> dữ liệu không đổi như color.xml, string.xml, styles.xml. Các tệp này phải được viết đúng chính tả.
drawable -> pics {jpeg, png, ...}; Đặt tên cho chúng bất cứ điều gì.
mipmap -> nhiều bức ảnh hơn. được sử dụng cho biểu tượng ứng dụng?
xml -> nhiều tệp xml hơn.
src -> hoạt động giống như JavaScript trong html. tệp bố cục sẽ bắt đầu chế độ xem bắt đầu và tệp java của bạn sẽ kiểm soát động các phần tử thẻ và kích hoạt các sự kiện. Các sự kiện cũng có thể được kích hoạt trực tiếp trong layout.xml giống như trong html.
AndroidManifest.xml -> Tệp này ghi lại nội dung ứng dụng của bạn. Tên ứng dụng, Loại chương trình, các quyền cần thiết, v.v. Điều này dường như làm cho Android khá an toàn. Các chương trình thực sự không thể làm những gì họ không yêu cầu trong Manifest.
Hiện có 4 loại chương trình Android, một hoạt động, một dịch vụ, một nhà cung cấp nội dung và một bộ thu phát sóng. Bàn phím của chúng tôi sẽ là một dịch vụ, cho phép nó chạy ở chế độ nền. Nó sẽ không xuất hiện trong danh sách các ứng dụng để khởi chạy; nhưng nó có thể được gỡ cài đặt.
Để biên dịch ứng dụng của bạn, hãy liên quan đến gradle và ký ứng dụng. Bạn có thể nghiên cứu cái đó hoặc sử dụng APK Builder cho android. Nó là siêu dễ dàng.
Bây giờ chúng ta đã hiểu về sự phát triển của Android, hãy tạo các tệp và thư mục.
Tạo các tệp và thư mục như tôi đã thảo luận ở trên. Thư mục của tôi sẽ trông như sau:
Hãy nhớ rằng nếu bạn đang sử dụng một lý tưởng như Android Studio, nó có thể có một tệp dự án.
A: NumPad / 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: NumPad / 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: NumPad / res / xml / method.xml
<?xml version="1.0" encoding="utf-8"?>
<input-method xmlns:android="http://schemas.android.com/apk/res/android">
<subtype android:imeSubtypeMode="keyboard"/>
</input-method>
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>
Tất nhiên điều này có thể dễ dàng chỉnh sửa theo ý muốn của bạn. Bạn thậm chí có thể sử dụng hình ảnh thay vì từ lf cho nhãn.
Suragch đã không chứng minh các tệp trong thư mục giá trị và cho rằng chúng tôi có quyền truy cập vào Android Studio; tự động tạo chúng. Điều tốt là tôi có Trình tạo APK.
E: NumPad / res / giá trị / màu sắc.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: NumPad / res / giá trị / string.xml
<resources>
<string name="app_name">Suragch NumPad</string>
</resources>
G: NumPad / res / values / styles.xml
<resources>
<!-- Base application theme. -->
<style name="AppTheme" parent="android:Theme.Material.Light.DarkActionBar">
<!-- Customize your theme here. -->
</style>
</resources>
H: Numpad / AndroidManifest.xml
Đây là tập tin thực sự cần thiết để tranh luận. Ở đây tôi cảm thấy tôi sẽ không bao giờ biên dịch chương trình của mình. nức nở. nức nở. Nếu bạn kiểm tra câu trả lời của Suracgh, bạn sẽ thấy anh ấy để trống tập hợp trường đầu tiên và thêm thẻ hoạt động vào tệp này. Như tôi đã nói, có bốn loại chương trình Android. Hoạt động là một ứng dụng thông thường có biểu tượng trình khởi chạy. Numpad này không phải là một hoạt động! Hơn nữa, anh ta không thực hiện bất kỳ hoạt động nào.
Bạn bè của tôi không bao gồm thẻ hoạt động. Chương trình của bạn sẽ biên dịch và khi bạn cố gắng khởi chạy, nó sẽ bị lỗi! Đối với xmlns: android và using-sdk; Tôi không thể giúp bạn ở đó. Chỉ cần thử cài đặt của tôi nếu chúng hoạt động.
Như bạn có thể thấy, có một thẻ dịch vụ, thẻ này đăng ký nó như một dịch vụ. Ngoài ra service.android:name phải là tên của dịch vụ mở rộng lớp công khai trong tệp java của chúng tôi. Nó PHẢI được viết hoa tương ứng. Ngoài ra, gói là tên của gói mà chúng tôi đã khai báo trong tệp 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
Lưu ý: Tôi nghĩ java là một thay thế cho src.
Đây là một tệp sự cố khác nhưng không gây tranh cãi như tệp kê khai. Như tôi biết Java đủ tốt để biết cái gì là cái gì, cái gì không. Tôi hầu như không biết xml và cách nó liên quan đến sự phát triển của Android!
Vấn đề ở đây là anh ta không nhập bất cứ thứ gì! Ý tôi là, anh ấy đã đưa cho chúng tôi một tệp "hoàn chỉnh" sử dụng những cái tên không thể giải quyết được! InputMethodService, Bàn phím, v.v ... Đó là cách làm không tốt, thưa ông Suragch. Cảm ơn bạn đã giúp tôi nhưng bạn mong đợi mã sẽ biên dịch như thế nào nếu không thể giải quyết các tên?
Sau đây là phiên bản đã được chỉnh sửa chính xác. Tôi chỉ tình cờ nhận được một vài gợi ý để đưa tôi đến đúng nơi để tìm hiểu chính xác những gì cần nhập.
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() { }
}
Biên dịch và ký dự án của bạn.
Đây là nơi tôi không biết gì với tư cách là một nhà phát triển Android mới. Tôi muốn học nó theo cách thủ công, vì tôi tin rằng các lập trình viên thực sự có thể biên dịch theo cách thủ công.
Tôi nghĩ gradle là một trong những công cụ để biên dịch và đóng gói thành apk. apk có vẻ giống như một tệp jar hoặc một tệp rar cho tệp zip. Sau đó, có hai loại ký. khóa gỡ lỗi không được phát trên cửa hàng chơi và khóa cá nhân.
Hãy giúp ông Saragch một tay. Và cảm ơn bạn đã xem video của tôi. Thích, đăng ký.
Có cùng một vấn đề. Lúc đầu, tôi đã sử dụng bố cục bảng nhưng bố cục liên tục thay đổi sau một lần nhấn nút. Mặc dù vậy, thấy trang này rất hữu ích. http://mobile.tutsplus.com/tutorials/android/android-user-interface-design-creating-a-numeric-keypad-with-gridlayout/