Chcę zrobić niestandardową klawiaturę. Nie wiem, jak to zrobić za pomocą XML i Java. Poniższe zdjęcie przedstawia model klawiatury, którą chcę wykonać. Potrzebuje tylko liczb.
Chcę zrobić niestandardową klawiaturę. Nie wiem, jak to zrobić za pomocą XML i Java. Poniższe zdjęcie przedstawia model klawiatury, którą chcę wykonać. Potrzebuje tylko liczb.
Odpowiedzi:
Przede wszystkim będziesz potrzebował keyboard.xml
pliku, który zostanie umieszczony w res/xml
folderze (jeśli folder nie istnieje, utworzył go).
<?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>
** Pamiętaj, że będziesz musiał utworzyć backspace
plik do rysowania i umieścić go w folderze res / drawable-ldpi o bardzo małym rozmiarze (np. 18x18 pikseli)
Następnie w pliku xml, którego chcesz użyć (gdzie znajduje się Twój TextView), powinieneś dodać następujący kod:
<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>
** Zauważ, że plik xml, który umieścisz android.inputmethodservice.KeyboardView
, musi być RelativeLayout
, aby móc ustawić alignParentBottom="true"
(Zwykle klawiatury są prezentowane na dole ekranu)
Następnie musisz dodać następujący kod w onCreate
funkcji Activity
obsługującej element TextView
, do którego chcesz dołączyć klawiaturę
// 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);
** Zauważ, że mKeyboard
i mKeyboardView
są to prywatne zmienne klasowe, które musisz utworzyć.
Następnie potrzebujesz następującej funkcji do otwierania klawiatury (musisz powiązać ją z TextView poprzez onClick
właściwość 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);
}
I wreszcie potrzebujesz narzędzia OnKeyboardActionListener
, które obsłuży Twoje wydarzenia
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() {
}
};
Mam nadzieję, że to pomoże !!!
Większość kodu znalezionego tutaj
____________________________________________________________-
EDYTOWAĆ:
Ponieważ KeyboardView jest przestarzały od poziomu 29 interfejsu API, możesz znaleźć jego kod w tej witrynie i utworzyć klasę w kodzie przed zaimplementowaniem klawiatury, jak opisano powyżej.
W tej odpowiedzi opisano, jak utworzyć niestandardową klawiaturę systemową, której można używać w dowolnej aplikacji zainstalowanej przez użytkownika na telefonie. Jeśli chcesz stworzyć klawiaturę, która będzie używana tylko w Twojej aplikacji, zobacz moją drugą odpowiedź .
Poniższy przykład będzie wyglądał następująco. Możesz go zmodyfikować dla dowolnego układu klawiatury.
Poniższe kroki pokazują, jak utworzyć działającą niestandardową klawiaturę systemową. W miarę możliwości starałem się usunąć niepotrzebny kod. Jeśli potrzebujesz innych funkcji, na końcu zamieściłem linki do dalszej pomocy.
Nazwałem swój projekt „Klawiatura niestandardowa”. Nazwij to, jak chcesz. Nie ma tu nic specjalnego. Po prostu zostawię MainActivity
i „Hello World!” układ, jaki jest.
Dodaj następujące dwa pliki do res/layout
folderu aplikacji :
keyboard_view.xml
Ten widok jest jak kontener, w którym znajdzie się nasza klawiatura. W tym przykładzie jest tylko jedna klawiatura, ale możesz dodać inne klawiatury i wymieniać je z niej 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
Podgląd klawisza to układ, który pojawia się po naciśnięciu klawisza na klawiaturze. Pokazuje tylko, jaki klawisz naciskasz (na wypadek, gdybyś zakrywał go dużymi, grubymi palcami). To nie jest wyskakujące okienko wielokrotnego wyboru. W tym celu sprawdź widok Kandydaci .
<?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>
Utwórz xml
folder w swoim res
folderze. (Kliknij prawym przyciskiem myszy res
i wybierz Nowy> Katalog ).
Następnie dodaj do niego następujące dwa pliki xml. (Kliknij xml
folder prawym przyciskiem myszy i wybierz Nowy> Plik zasobów XML) .
number_pad.xml
Tutaj zaczyna się robić ciekawiej. To Keyboard
definiuje układ z klawiszami .
<?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>
Oto kilka rzeczy, na które należy zwrócić uwagę:
keyWidth
: To jest domyślna szerokość każdego klawisza. Te 20%p
środki, które każdy klawisz powinien trwać 20% szerokości p Arent. Można go jednak zastąpić pojedynczymi klawiszami, jak widać z klawiszami Delete i Enter w trzecim rzędzie.keyHeight
: Jest tutaj zakodowany na sztywno, ale możesz użyć czegoś takiego, jak @dimen/key_height
ustawić go dynamicznie dla różnych rozmiarów ekranu.Gap
: Pozioma i pionowa przerwa określa, ile wolnego miejsca między klawiszami. Nawet jeśli ustawisz to na, 0px
nadal jest mała luka.codes
: Może to być kod Unicode lub niestandardowa wartość kodu, która określa, co się dzieje lub co jest wprowadzane po naciśnięciu klawisza. Sprawdź, keyOutputText
czy chcesz wprowadzić dłuższy ciąg Unicode.keyLabel
: To jest tekst wyświetlany na klawiszu.keyEdgeFlags
: Wskazuje, do której krawędzi ma być wyrównany wpust.isRepeatable
: Jeśli przytrzymasz wciśnięty klawisz, wejście będzie powtarzane.method.xml
Ten plik informuje system o dostępnych podtypach metod wejściowych. Załączam tutaj tylko minimalną wersję.
<?xml version="1.0" encoding="utf-8"?>
<input-method
xmlns:android="http://schemas.android.com/apk/res/android">
<subtype
android:imeSubtypeMode="keyboard"/>
</input-method>
Utwórz nowy plik Java. Nazwijmy to MyInputMethodService
. Ten plik łączy wszystko razem. Obsługuje dane wejściowe otrzymane z klawiatury i wysyła je do dowolnego widoku, który je otrzymuje ( EditText
na przykład).
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() { }
}
Uwagi:
OnKeyboardActionListener
nasłuchuje dane z klawiatury. Wymaga również wszystkich tych pustych metod w tym przykładzie.InputConnection
jest to, co jest używane do wysyłania danych wejściowych do innego widoku, takiego jak plik EditText
.Umieszczam to na końcu zamiast na początku, ponieważ odnosi się do plików, które już dodaliśmy powyżej. Aby zarejestrować klawiaturę niestandardową jako klawiaturę systemową, musisz dodać service
sekcję do pliku AndroidManifest.xml . Umieść to w application
sekcji po 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>
Otóż to! Teraz powinieneś móc uruchomić swoją aplikację. Jednak niewiele zobaczysz, dopóki nie włączysz klawiatury w ustawieniach.
Każdy użytkownik, który chce korzystać z Twojej klawiatury, będzie musiał ją włączyć w ustawieniach Androida. Aby uzyskać szczegółowe instrukcje, jak to zrobić, zobacz poniższy link:
Oto podsumowanie:
Teraz powinieneś być w stanie używać klawiatury w dowolnym miejscu, w którym możesz wpisać Androida.
Powyższa klawiatura jest użyteczna, ale aby stworzyć klawiaturę, której inne osoby będą chciały używać, prawdopodobnie będziesz musiał dodać więcej funkcji. Przeczytaj poniższe linki, aby dowiedzieć się, jak to zrobić.
Nie podoba ci się, jak standard KeyboardView
wygląda i zachowuje się? Ja na pewno nie. Wygląda na to, że nie był aktualizowany od czasu Androida 2.0. A co z tymi wszystkimi niestandardowymi klawiaturami w Sklepie Play? Nie wyglądają jak brzydka klawiatura powyżej.
Dobra wiadomość jest taka, że możesz całkowicie dostosować wygląd i zachowanie własnej klawiatury. Będziesz musiał wykonać następujące czynności:
ViewGroup
. Możesz wypełnić go Button
s lub nawet stworzyć własne niestandardowe widoki kluczy, które są podklasą View
. Jeśli używasz widoków wyskakujących, zanotuj to .onKeyClicked(String text)
lub onBackspace()
.keyboard_view.xml
, key_preview.xml
lub number_pad.xml
opisane w kierunkach wyżej, gdyż są to wszystko do normy KeyboardView
. Zajmiesz się wszystkimi tymi aspektami interfejsu użytkownika w swoim niestandardowym widoku.MyInputMethodService
klasie zaimplementuj niestandardowy odbiornik klawiatury zdefiniowany w klasie klawiatury. Jest to miejsce KeyboardView.OnKeyboardActionListener
, które nie jest już potrzebne.MyInputMethodService
klasy onCreateInputView()
utwórz i zwróć instancję klawiatury niestandardowej. Nie zapomnij ustawić niestandardowego nasłuchiwania klawiatury na this
.Ta odpowiedź wyjaśnia, jak skonfigurować niestandardową klawiaturę do użytku wyłącznie w aplikacji. Jeśli chcesz stworzyć klawiaturę systemową, której można używać w dowolnej aplikacji, zobacz moją drugą odpowiedź .
Przykład będzie wyglądał następująco. Możesz go zmodyfikować dla dowolnego układu klawiatury.
Nazwałam swój projekt InAppKeyboard
. Zadzwoń, jak chcesz.
Układ klawiatury
Dodaj plik układu do res/layout
folderu. Zadzwoniłem do mnie keyboard
. Klawiatura będzie niestandardowym widokiem złożonym , który zostanie nadmuchany z tego pliku układu xml. Możesz użyć dowolnego układu do rozmieszczenia klawiszy, ale ja używam LinearLayout
. Zwróć uwagę na merge
tagi.
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>
Układ zajęć
Dla celów demonstracyjnych nasza aktywność ma jeden, EditText
a klawiatura jest na dole. Nazwałem niestandardowy widok klawiatury MyKeyboard
. (Wkrótce dodamy ten kod, więc na razie zignoruj błąd). Zaletą umieszczenia całego kodu klawiatury w jednym widoku jest to, że ułatwia on ponowne użycie w innym działaniu lub aplikacji.
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>
Dodaj nowy plik Java. Zadzwoniłem do mnie MyKeyboard
.
Najważniejszą rzeczą, na którą należy tutaj zwrócić uwagę, jest to, że nie ma stałego połączenia z żadnym EditText
lub Activity
. Ułatwia to podłączenie go do dowolnej aplikacji lub działania, które tego potrzebuje. Ten niestandardowy widok klawiatury używa również znaku InputConnection
, który naśladuje sposób, w jaki klawiatura systemowa komunikuje się z plikiem EditText
. W ten sposób unikamy twardych linków.
MyKeyboard
jest widokiem złożonym, który rozszerza układ widoku, który zdefiniowaliśmy powyżej.
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;
}
}
W przypadku klawiatur systemowych system Android używa InputMethodManager, aby wskazać klawiaturę na fokus EditText
. W tym przykładzie działanie zajmie jego miejsce, podając łącze z EditText
naszej klawiatury niestandardowej do.
Ponieważ nie używamy klawiatury systemowej, musimy ją wyłączyć, aby nie pojawiała się po dotknięciu EditText
. Po drugie, musimy pobrać go InputConnection
z EditText
i przekazać do naszej klawiatury.
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);
}
}
Jeśli Twoja aktywność ma wiele tekstów edycji, będziesz musiał napisać kod, aby przekazać odpowiednie teksty edycji InputConnection
do klawiatury. (Możesz to zrobić, dodając OnFocusChangeListener
i OnClickListener
do EditTexts. Zobacz ten artykuł, aby omówić ten temat). Możesz także chcieć ukryć lub pokazać klawiaturę w odpowiednim momencie.
Otóż to. Powinieneś móc teraz uruchomić przykładową aplikację i wprowadzić lub usunąć tekst zgodnie z potrzebami. Następnym krokiem jest zmodyfikowanie wszystkiego, aby dopasować je do własnych potrzeb. Na przykład w niektórych moich klawiaturach użyłem TextViews zamiast przycisków, ponieważ łatwiej jest je dostosować.
TextView
raczej a, Button
jeśli chcesz, aby klucze wyglądały lepiej. Następnie po prostu ustaw tło, które można narysować, a po naciśnięciu zmieni stan wyglądu.View
a niestandardowe klawiatury są podklasami ViewGroup
. Klawiatura rozkłada wszystkie klawisze programowo. Klawisze wykorzystują interfejs do komunikacji z klawiaturą (podobnie jak fragmenty komunikują się z działaniem). Nie jest to konieczne, jeśli potrzebujesz tylko jednego układu klawiatury, ponieważ układ xml działa dobrze do tego. Ale jeśli chcesz zobaczyć przykład tego, nad czym pracowałem, sprawdź wszystkie Key*
i Keyboard*
zajęcia tutaj . Zauważ, że używam tam również widoku kontenera, którego funkcją jest włączanie i wyłączanie klawiatur.InputMethodManager#showInputMethodPicker()
. Jeśli jednak oryginalna klawiatura nie ma takiego klawisza, jedynym sposobem, w jaki użytkownicy mogą przełączyć się na klawiaturę, jest zrobienie tego ręcznie w ustawieniach systemu. Apple jest lepszy od Androida w tej dziedzinie, ponieważ Apple wymaga, aby wszystkie klawiatury miały klawisz przełączania klawiatury.
EditText
s, będziesz musiał dodać onFocusChangedListener
do nich znak, aby po uzyskaniu fokusu można było przypisać InputConnection
od bieżącego EditText
do niestandardowej klawiatury.
Zastosowanie KeyboardView
:
KeyboardView kbd = new KeyboardView(context);
kbd.setKeyboard(new Keyboard(this, R.xml.custom));
kbd.setOnKeyboardActionListener(new OnKeyboardActionListener() {
....
}
teraz masz kbd
co jest normalnym widokiem.
Fajną rzeczą w tym jest to, że R.xml.custom
odnosi się do /res/xml/custom.xml
, który definiuje w xml układ klawiatury. Więcej informacji na temat tego pliku można znaleźć tutaj: Keyboard , Keyboard.Row , Keyboard.Key .
Oto przykładowy projekt dla miękkiej klawiatury.
https://developer.android.com/guide/topics/text/creating-input-method.html
Twoje powinny znajdować się w tych samych wierszach z innym układem.
Edycja: Jeśli potrzebujesz klawiatury tylko w swojej aplikacji, jest to bardzo proste! Utwórz układ liniowy z orientacją pionową i utwórz w nim 3 układy liniowe z orientacją poziomą. Następnie umieść przyciski z każdego wiersza w każdym z tych poziomych układów liniowych i przypisz do przycisków właściwość wagi. Użyj android: layout_weight = 1 dla wszystkich, aby były równomiernie rozmieszczone.
To rozwiąże. Jeśli nie otrzymałeś tego, czego się spodziewałeś, prześlij kod tutaj, a my jesteśmy tutaj, aby Ci pomóc!
Jeden z najlepiej udokumentowanych przykładów, jakie znalazłem.
http://www.fampennings.nl/maarten/android/09keyboard/index.htm
KeyboardView
dostarczany jest powiązany plik XML i kod źródłowy.
Niedawno natknąłem się na ten post, gdy próbowałem zdecydować, jakiej metody użyć do stworzenia własnej niestandardowej klawiatury. Uznałem, że API systemu Android jest bardzo ograniczone, więc zdecydowałem się stworzyć własną klawiaturę w aplikacji. Wykorzystując odpowiedź Suragcha jako podstawę moich badań, przystąpiłem do zaprojektowania własnego komponentu klawiatury . Jest opublikowany na GitHub z licencją MIT. Miejmy nadzieję, że zaoszczędzi to komuś dużo czasu i bólu głowy.
Architektura jest dość elastyczna. Istnieje jeden widok główny (CustomKeyboardView), który można wstrzyknąć za pomocą dowolnego układu klawiatury i kontrolera.
Musisz tylko zadeklarować CustomKeyboardView w swoim pliku XML aktywności (możesz to również zrobić programowo):
<com.donbrody.customkeyboard.components.keyboard.CustomKeyboardView
android:id="@+id/customKeyboardView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true" />
Następnie zarejestruj w nim swój EditText i powiedz, jakiego typu klawiatury mają używać:
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 obsługuje resztę!
Mam piłkę za pomocą klawiatury Number, NumberDecimal i QWERTY. Zapraszam do pobrania i tworzenia własnych układów i kontrolerów. To wygląda tak:
Nawet jeśli nie jest to architektura, na którą zdecydujesz się wybrać, miejmy nadzieję, że pomocne będzie zapoznanie się z kodem źródłowym działającej klawiatury w aplikacji.
Ponownie, oto link do projektu: Niestandardowa klawiatura w aplikacji
Cóż, Suragch udzielił jak dotąd najlepszej odpowiedzi, ale pominął pewne drobne rzeczy, które były ważne przy kompilacji aplikacji.
Mam nadzieję dać lepszą odpowiedź niż Suragch, poprawiając jego odpowiedź. Dodam wszystkie brakujące elementy, których nie umieścił.
Skompilowałem mój apk za pomocą aplikacji na Androida, APK Builder 1.1.0. Więc zacznijmy.
Aby zbudować aplikację na Androida, potrzebujemy kilku plików i folderów, które są uporządkowane w określonym formacie i odpowiednio pisane wielkimi literami.
res layout -> pliki xml przedstawiające wygląd aplikacji na telefonie. Podobnie jak HTML kształtuje wygląd strony internetowej w przeglądarce. Zezwalanie na odpowiednie dopasowanie aplikacji do ekranów.
wartości -> stałe dane, takie jak colors.xml, strings.xml, styles.xml. Te pliki muszą mieć poprawną pisownię.
do rysowania -> zdjęcia {jpeg, png, ...}; Nazwij je dowolnie.
mipmap -> więcej fotek. używany do ikony aplikacji?
xml -> więcej plików xml.
src -> działa jak JavaScript w html. Pliki układu zainicjują widok początkowy, a plik java będzie dynamicznie kontrolować elementy znaczników i zdarzenia wyzwalające. Zdarzenia można również aktywować bezpośrednio w pliku layout.xml, tak jak w html.
AndroidManifest.xml -> Ten plik rejestruje, o czym jest Twoja aplikacja. Nazwa aplikacji, typ programu, wymagane uprawnienia itp. To sprawia, że Android jest raczej bezpieczny. Programy dosłownie nie mogą zrobić tego, o co nie poprosiły w Manifeście.
Obecnie istnieją 4 typy programów na Androida: aktywność, usługa, dostawca treści i odbiorca transmisji. Nasza klawiatura będzie usługą umożliwiającą jej działanie w tle. Nie pojawi się na liście aplikacji do uruchomienia; ale można go odinstalować.
Skompilowanie aplikacji obejmuje Gradle i podpisywanie APK. Możesz go zbadać lub użyć aplikacji APK Builder dla Androida. To bardzo proste.
Teraz, gdy rozumiemy rozwój Androida, stwórzmy pliki i foldery.
Utwórz pliki i foldery, jak omówiłem powyżej. Mój katalog będzie wyglądał następująco:
Pamiętaj, że jeśli używasz ide, takiego jak Android Studio, może on zawierać plik projektu.
Odp .: 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>
Oczywiście można to łatwo edytować według własnych upodobań. Możesz nawet użyć obrazów zamiast słów dla etykiety.
Suragch nie zademonstrował plików w folderze wartości i założył, że mamy dostęp do Android Studio; która automatycznie je tworzy. Dobrze, że mam APK Builder.
E: NumPad / res / values / colors.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 / values / strings.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
To jest plik, który naprawdę czekał na rywalizację. Tutaj poczułem, że nigdy nie skompiluję swojego programu. szloch. szloch. Jeśli zaznaczysz odpowiedź Suracgha, zobaczysz, że pozostawia pierwszy zestaw pól pustych i dodaje znacznik aktywności w tym pliku. Jak powiedziałem, istnieją cztery rodzaje programów na Androida. Aktywność to zwykła aplikacja z ikoną programu uruchamiającego. Ten numpad nie jest zajęciem! Ponadto nie podejmował żadnych działań.
Moi przyjaciele nie dołączają tagu aktywności. Twój program się skompiluje, a przy próbie uruchomienia ulegnie awarii! Jeśli chodzi o xmlns: android i uses-sdk; Nie mogę ci tam pomóc. Po prostu wypróbuj moje ustawienia, jeśli działają.
Jak widać, istnieje tag serwisowy, który rejestruje go jako usługę. Również service.android:name musi być nazwą usługi rozszerzającej klasę publiczną w naszym pliku java. MUSI być odpowiednio wielką literą. Pakiet jest również nazwą pakietu, który zadeklarowaliśmy w pliku 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
Uwaga: myślę, że java jest alternatywą dla src.
To był kolejny problem, ale nie tak sporny jak plik manifestu. Ponieważ znam Javę na tyle dobrze, że wiem, co jest czym, a co nie. Ledwo znam xml i jak to się wiąże z programowaniem na Androida!
Problem polegał na tym, że niczego nie importował! To znaczy, dał nam „kompletny” plik, który używa nazw, których nie można było rozwiązać! InputMethodService, Keyboard, itp. To zła praktyka, panie Suragch. Dziękuję za pomoc, ale jak spodziewałeś się kompilacji kodu, jeśli nazwy nie mogą zostać rozwiązane?
Poniżej znajduje się poprawnie zredagowana wersja. Po prostu natknąłem się na kilka wskazówek, które doprowadziły mnie we właściwe miejsce, aby dowiedzieć się, co dokładnie zaimportować.
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() { }
}
Skompiluj i podpisz swój projekt.
W tym miejscu nie mam pojęcia, jako początkujący programista Android. Chciałbym nauczyć się tego ręcznie, ponieważ uważam, że prawdziwi programiści mogą kompilować ręcznie.
Myślę, że gradle jest jednym z narzędzi do kompilowania i pakowania do apk. apk wygląda jak plik jar lub rar dla pliku zip. Istnieją zatem dwa rodzaje podpisów. klucz debugowania, który nie jest dozwolony w sklepie Play i klucz prywatny.
Pomóżmy panu Saragchowi. Dziękuję za obejrzenie mojego filmu. Polub, zasubskrybuj.
Miałem ten sam problem. Na początku użyłem układu tabeli, ale układ zmieniał się po naciśnięciu przycisku. Jednak ta strona okazała się bardzo przydatna. http://mobile.tutsplus.com/tutorials/android/android-user-interface-design-creating-a-numeric-keypad-with-gridlayout/